Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: bugs/issues with the message queue #124

Merged
merged 1 commit into from
Nov 12, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 42 additions & 22 deletions src/message_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ static void cqueue_mark_read(ToxWindow *self, struct cqueue_msg *msg)
/* removes message with matching receipt from queue, writes to log and updates line to show the message was received. */
void cqueue_remove(ToxWindow *self, Tox *m, uint32_t receipt)
{
struct chatlog *log = self->chatwin->log;
struct chat_queue *q = self->chatwin->cqueue;
struct cqueue_msg *msg = q->root;

Expand All @@ -107,13 +108,16 @@ void cqueue_remove(ToxWindow *self, Tox *m, uint32_t receipt)
continue;
}

char selfname[TOX_MAX_NAME_LENGTH];
tox_self_get_name(m, (uint8_t *) selfname);
if (log->log_on) {
char selfname[TOX_MAX_NAME_LENGTH];
tox_self_get_name(m, (uint8_t *) selfname);

size_t len = tox_self_get_name_size(m);
selfname[len] = '\0';
size_t len = tox_self_get_name_size(m);
selfname[len] = 0;

write_to_log(msg->message, selfname, log, msg->type == OUT_ACTION);
}

write_to_log(msg->message, selfname, self->chatwin->log, msg->type == OUT_ACTION);
cqueue_mark_read(self, msg);

struct cqueue_msg *next = msg->next;
Expand All @@ -123,24 +127,37 @@ void cqueue_remove(ToxWindow *self, Tox *m, uint32_t receipt)
next->prev = NULL;
}

free(msg);
q->root = next;
} else {
struct cqueue_msg *prev = msg->prev;
free(msg);
prev->next = next;
next->prev = prev;
}

free(msg);

return;
}
}

/* We use knowledge of toxcore internals (bad!) to determine that if we haven't received a read receipt
* for a sent packet after this amount of time, the connection has been severed and the packet needs
* to be re-sent despite toxcore not returning an error on its initial send.
*/
// We use knowledge of toxcore internals (bad!) to determine that if we haven't received a read receipt for a
// sent packet after this amount of time, the connection has been severed and the packet needs to be re-sent.
#define TRY_SEND_TIMEOUT 32

/*
* Marks all timed out messages in queue as unsent.
*/
static void cqueue_check_timeouts(struct cqueue_msg *msg)
{
while (msg) {
if (timed_out(msg->last_send_try, TRY_SEND_TIMEOUT)) {
msg->receipt = -1;
}

msg = msg->next;
}
}

/*
* Tries to send all messages in the send queue in sequential order.
* If a message fails to send the function will immediately return.
Expand All @@ -151,21 +168,24 @@ void cqueue_try_send(ToxWindow *self, Tox *m)
struct cqueue_msg *msg = q->root;

while (msg) {
if (msg->receipt == -1) {
TOX_ERR_FRIEND_SEND_MESSAGE err;
Tox_Message_Type type = msg->type == OUT_MSG ? TOX_MESSAGE_TYPE_NORMAL : TOX_MESSAGE_TYPE_ACTION;
uint32_t receipt = tox_friend_send_message(m, self->num, type, (uint8_t *) msg->message, msg->len, &err);
if (msg->receipt != -1) {
// we can no longer try to send unsent messages until we get receipts for our previous sent
// messages, but we continue to iterate the list, checking timestamps for any further
// successfully sent messages that have not yet gotten a receipt.
cqueue_check_timeouts(msg);
return;
}

if (err != TOX_ERR_FRIEND_SEND_MESSAGE_OK) {
return;
}
TOX_ERR_FRIEND_SEND_MESSAGE err;
Tox_Message_Type type = msg->type == OUT_MSG ? TOX_MESSAGE_TYPE_NORMAL : TOX_MESSAGE_TYPE_ACTION;
uint32_t receipt = tox_friend_send_message(m, self->num, type, (uint8_t *) msg->message, msg->len, &err);

msg->receipt = receipt;
msg->last_send_try = get_unix_time();
} else if (timed_out(msg->last_send_try, TRY_SEND_TIMEOUT)) { // unlikely but possible
msg->receipt = -1;
if (err != TOX_ERR_FRIEND_SEND_MESSAGE_OK) {
return;
}

msg->receipt = receipt;
msg->last_send_try = get_unix_time();
msg = msg->next;
}
}