From 2073d02c33a2bc8478099c66985f2a69854ecaf5 Mon Sep 17 00:00:00 2001 From: sudden6 Date: Thu, 13 Jan 2022 21:11:34 +0100 Subject: [PATCH] fix: don't count filetransfer as sending until accepted This fixes high CPU load in c-toxcore due to started but not accepted file transfers causing lots of iterations in do_all_filetransfers(...). Additionally this skips expensive calls max_speed_reached(...). --- toxcore/Messenger.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 31573d70..94e2c47f 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -1148,8 +1148,6 @@ long int new_filesender(const Messenger *m, int32_t friendnumber, uint32_t file_ memcpy(ft->id, file_id, FILE_ID_LENGTH); - ++m->friendlist[friendnumber].num_sending_files; - return i; } @@ -1255,11 +1253,12 @@ int file_control(const Messenger *m, int32_t friendnumber, uint32_t filenumber, if (send_file_control_packet(m, friendnumber, send_receive, file_number, control, nullptr, 0)) { if (control == FILECONTROL_KILL) { - ft->status = FILESTATUS_NONE; - - if (send_receive == 0) { + if (send_receive == 0 && (ft->status == FILESTATUS_TRANSFERRING || ft->status == FILESTATUS_FINISHED)) { + // We are actively sending that file, remove from list --m->friendlist[friendnumber].num_sending_files; } + + ft->status = FILESTATUS_NONE; } else if (control == FILECONTROL_PAUSE) { ft->paused |= FILE_PAUSE_US; } else if (control == FILECONTROL_ACCEPT) { @@ -1465,15 +1464,13 @@ static bool do_all_filetransfers(Messenger *m, int32_t friendnumber, void *userd return false; } - if (max_speed_reached(m->net_crypto, friend_connection_crypt_connection_id( - m->fr_c, friendcon->friendcon_id))) { - LOGGER_TRACE(m->log, "Maximum connection speed reached"); - // connection doesn't support any more data - return false; - } - struct File_Transfers *const ft = &friendcon->file_sending[i]; + if (ft->status == FILESTATUS_NONE || ft->status == FILESTATUS_NOT_ACCEPTED) { + // Filetransfers not actively sending, nothing to do + continue; + } + // If the file transfer is complete, we request a chunk of size 0. if (ft->status == FILESTATUS_FINISHED && friend_received_packet(m, friendnumber, ft->last_packet_number) == 0) { if (m->file_reqchunk) { @@ -1483,9 +1480,7 @@ static bool do_all_filetransfers(Messenger *m, int32_t friendnumber, void *userd // Now it's inactive, we're no longer sending this. ft->status = FILESTATUS_NONE; --friendcon->num_sending_files; - } - - if (ft->status == FILESTATUS_TRANSFERRING && ft->paused == FILE_PAUSE_NOT) { + } else if (ft->status == FILESTATUS_TRANSFERRING && ft->paused == FILE_PAUSE_NOT) { if (ft->size == 0) { /* Send 0 data to friend if file is 0 length. */ file_data(m, friendnumber, i, 0, nullptr, 0); @@ -1508,6 +1503,14 @@ static bool do_all_filetransfers(Messenger *m, int32_t friendnumber, void *userd // The allocated slot is no longer free. --*free_slots; } + + // Must be last to allow finishing file transfers + if (max_speed_reached(m->net_crypto, friend_connection_crypt_connection_id( + m->fr_c, friendcon->friendcon_id))) { + LOGGER_TRACE(m->log, "Maximum connection speed reached"); + // connection doesn't support any more data + return false; + } } return true; @@ -1614,6 +1617,7 @@ static int handle_filecontrol(Messenger *m, int32_t friendnumber, uint8_t receiv case FILECONTROL_ACCEPT: { if (receive_send && ft->status == FILESTATUS_NOT_ACCEPTED) { ft->status = FILESTATUS_TRANSFERRING; + ++m->friendlist[friendnumber].num_sending_files; } else { if (ft->paused & FILE_PAUSE_OTHER) { ft->paused ^= FILE_PAUSE_OTHER; @@ -1652,12 +1656,12 @@ static int handle_filecontrol(Messenger *m, int32_t friendnumber, uint8_t receiv m->file_filecontrol(m, friendnumber, real_filenumber, control_type, userdata); } - ft->status = FILESTATUS_NONE; - - if (receive_send) { + if (receive_send && (ft->status == FILESTATUS_TRANSFERRING || ft->status == FILESTATUS_FINISHED)) { --m->friendlist[friendnumber].num_sending_files; } + ft->status = FILESTATUS_NONE; + return 0; }