Fixed a crash related to file transfers

This commit is contained in:
WolverinDEV
2021-01-03 17:16:23 +01:00
parent 6a502e23f2
commit 960186d55e
7 changed files with 112 additions and 72 deletions
+34 -19
View File
@@ -145,7 +145,7 @@ bool FileClient::enqueue_network_buffer_bytes(const void *snd_buffer, size_t siz
return buffer_size > TRANSFER_MAX_CACHED_BYTES;
write_disconnected:
free_buffer(tbuffer);
deref_buffer(tbuffer);
return false;
}
@@ -163,7 +163,7 @@ size_t FileClient::flush_network_buffer() {
while(current_head) {
auto next = current_head->next;
free_buffer(current_head);
deref_buffer(current_head);
current_head = next;
}
@@ -723,20 +723,24 @@ void LocalFileTransfer::callback_transfer_network_write(int fd, short events, vo
while(true) {
{
std::lock_guard block{transfer->network_buffer.mutex};
buffer = transfer->network_buffer.buffer_head;
buffer_left_size = transfer->network_buffer.bytes;
}
if(!buffer) {
break;
if(!transfer->network_buffer.buffer_head) {
buffer_left_size = 0;
assert(transfer->network_buffer.bytes == 0);
break;
}
buffer = ref_buffer(transfer->network_buffer.buffer_head);
buffer_left_size = transfer->network_buffer.bytes;
}
const auto max_write_bytes = transfer->networking.throttle.bytes_left();
if(!max_write_bytes) break; /* network throttle */
assert(buffer->offset < buffer->length);
auto written = ::send(fd, buffer->data + buffer->offset, std::min(buffer->length - buffer->offset, max_write_bytes), MSG_DONTWAIT | MSG_NOSIGNAL);
auto written = ::send(fd, buffer->data + buffer->offset, std::min((size_t) (buffer->length - buffer->offset), max_write_bytes), MSG_DONTWAIT | MSG_NOSIGNAL);
if(written <= 0) {
deref_buffer(buffer);
if(errno == EAGAIN) {
transfer->add_network_write_event(false);
break;
@@ -795,27 +799,38 @@ void LocalFileTransfer::callback_transfer_network_write(int fd, short events, vo
if(buffer->length == buffer->offset) {
{
std::lock_guard block{transfer->network_buffer.mutex};
transfer->network_buffer.buffer_head = buffer->next;
if(!buffer->next)
transfer->network_buffer.buffer_tail = &transfer->network_buffer.buffer_head;
if(transfer->network_buffer.buffer_head == buffer) {
transfer->network_buffer.buffer_head = buffer->next;
if(!buffer->next)
transfer->network_buffer.buffer_tail = &transfer->network_buffer.buffer_head;
assert(transfer->network_buffer.bytes >= written);
transfer->network_buffer.bytes -= written;
buffer_left_size = transfer->network_buffer.bytes;
} else {
/* the buffer got remove */
}
}
deref_buffer(buffer);
} else {
std::lock_guard block{transfer->network_buffer.mutex};
if(transfer->network_buffer.buffer_head == buffer) {
assert(transfer->network_buffer.bytes >= written);
transfer->network_buffer.bytes -= written;
buffer_left_size = transfer->network_buffer.bytes;
} else {
/* the buffer got remove */
}
free_buffer(buffer);
} else {
std::lock_guard block{transfer->network_buffer.mutex};
assert(transfer->network_buffer.bytes >= written);
transfer->network_buffer.bytes -= written;
buffer_left_size = transfer->network_buffer.bytes;
}
transfer->timings.last_write = std::chrono::system_clock::now();
transfer->statistics.network_send.increase_bytes(written);
if(transfer->networking.throttle.increase_bytes(written))
deref_buffer(buffer);
if(transfer->networking.throttle.increase_bytes(written)) {
break; /* we've to slow down */
}
}
}