Fixed a crash related to file transfers
This commit is contained in:
@@ -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 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user