Ensure that messages are not sent during events.

Don't cause segfault in libtgl when add_log_event is called twice.
This commit is contained in:
mjentsch 2015-04-03 01:23:09 +02:00
parent 8a678f98cc
commit 1c7eebbe7c
3 changed files with 56 additions and 10 deletions

View file

@ -159,6 +159,30 @@ static void tgp_msg_send_done (struct tgl_state *TLS, void *callback_extra, int
}
}
static gboolean tgp_msg_send_schedule_cb (gpointer data) {
connection_data *conn = data;
conn->out_timer = 0;
struct tgp_msg_sending *D = NULL;
while ((D = g_queue_peek_head (conn->out_messages))) {
g_queue_pop_head (conn->out_messages);
tgl_do_send_message (D->TLS, D->to, D->msg, (int)strlen (D->msg), tgp_msg_send_done, NULL);
tgp_msg_sending_free (D);
}
return FALSE;
}
static void tgp_msg_send_schedule (struct tgl_state *TLS, gchar *chunk, tgl_peer_id_t to) {
connection_data *conn = TLS->ev_base;
struct tgp_msg_sending *D = tgp_msg_sending_init (TLS, chunk, to);
g_queue_push_tail (conn->out_messages, D);
if (conn->out_timer) {
purple_timeout_remove (conn->out_timer);
}
conn->out_timer = purple_timeout_add (0, tgp_msg_send_schedule_cb, conn);
}
static int tgp_msg_send_split (struct tgl_state *TLS, const char *message, tgl_peer_id_t to) {
int max = TGP_DEFAULT_MAX_MSG_SPLIT_COUNT;
if (max < 1) {
@ -172,8 +196,7 @@ static int tgp_msg_send_split (struct tgl_state *TLS, const char *message, tgl_p
while (size > start) {
int e = start + (int)TGP_MAX_MSG_SIZE;
gchar *chunk = g_utf8_substring (message, start, e);
tgl_do_send_message (TLS, to, chunk, (int)strlen (chunk), tgp_msg_send_done, NULL);
g_free (chunk);
tgp_msg_send_schedule (TLS, chunk, to);
start = e;
}
return 1;
@ -347,8 +370,7 @@ static time_t tgp_msg_oldest_relevant_ts (struct tgl_state *TLS) {
return days > 0 ? tgp_time_n_days_ago (days) : 0;
}
static void tgp_msg_process_ready (struct tgl_state *TLS)
{
static void tgp_msg_process_in_ready (struct tgl_state *TLS) {
connection_data *conn = TLS->ev_base;
struct tgp_msg_loading *C;
@ -366,11 +388,10 @@ static void tgp_msg_on_loaded_photo (struct tgl_state *TLS, void *extra, int suc
struct tgp_msg_loading *C = extra;
C->data = filename;
C->done = TRUE;
tgp_msg_process_ready (TLS);
tgp_msg_process_in_ready (TLS);
}
void tgp_msg_recv (struct tgl_state *TLS, struct tgl_message *M)
{
void tgp_msg_recv (struct tgl_state *TLS, struct tgl_message *M) {
connection_data *conn = TLS->ev_base;
struct tgp_msg_loading *C = tgp_msg_loading_init (TRUE, M);
@ -386,7 +407,6 @@ void tgp_msg_recv (struct tgl_state *TLS, struct tgl_message *M)
// TODO: load geo thumbnail
}
g_queue_push_tail (conn->new_messages, C);
tgp_msg_process_ready (TLS);
tgp_msg_process_in_ready (TLS);
}

View file

@ -80,12 +80,27 @@ struct tgp_msg_loading *tgp_msg_loading_init (int done, struct tgl_message *M) {
return C;
}
struct tgp_msg_sending *tgp_msg_sending_init (struct tgl_state *TLS, gchar *M, tgl_peer_id_t to) {
struct tgp_msg_sending *C = malloc (sizeof (struct tgp_msg_sending));
C->TLS = TLS;
C->msg = M;
C->to = to;
return C;
}
void tgp_msg_sending_free (gpointer data) {
struct tgp_msg_sending *C = data;
g_free (C->msg);
free (C);
}
connection_data *connection_data_init (struct tgl_state *TLS, PurpleConnection *gc, PurpleAccount *pa) {
connection_data *conn = g_new0 (connection_data, 1);
conn->TLS = TLS;
conn->gc = gc;
conn->pa = pa;
conn->new_messages = g_queue_new ();
conn->out_messages = g_queue_new ();
conn->pending_reads = g_queue_new ();
return conn;
}
@ -93,9 +108,11 @@ connection_data *connection_data_init (struct tgl_state *TLS, PurpleConnection *
void *connection_data_free (connection_data *conn) {
if (conn->write_timer) { purple_timeout_remove (conn->write_timer); }
if (conn->login_timer) { purple_timeout_remove (conn->login_timer); }
if (conn->out_timer) { purple_timeout_remove (conn->out_timer); }
tgp_g_queue_free_full (conn->pending_reads, pending_reads_free_cb);
tgp_g_queue_free_full (conn->new_messages, tgp_msg_loading_free);
tgp_g_queue_free_full (conn->out_messages, tgp_msg_sending_free);
tgp_g_list_free_full (conn->used_images, used_image_free);
tgprpl_xfer_free_all (conn);
tgl_free_all (conn->TLS);

View file

@ -33,10 +33,12 @@ typedef struct {
PurpleConnection *gc;
int updated;
GQueue *new_messages;
GQueue *out_messages;
GQueue *pending_reads;
GList *used_images;
guint write_timer;
guint login_timer;
guint out_timer;
int in_fallback_chat;
} connection_data;
@ -65,6 +67,12 @@ struct tgp_msg_loading {
void *data;
};
struct tgp_msg_sending {
struct tgl_state *TLS;
tgl_peer_id_t to;
gchar *msg;
};
void pending_reads_send_all (GQueue *queue, struct tgl_state *TLS);
void pending_reads_add (GQueue *queue, tgl_peer_id_t id);
struct message_text *message_text_init (struct tgl_message *M, gchar *text);
@ -74,6 +82,7 @@ void *connection_data_free (connection_data *conn);
connection_data *connection_data_init (struct tgl_state *TLS, PurpleConnection *gc, PurpleAccount *pa);
get_user_info_data* get_user_info_data_new (int show_info, tgl_peer_id_t peer);
struct tgp_msg_loading *tgp_msg_loading_init (int done, struct tgl_message *M);
struct tgp_msg_sending *tgp_msg_sending_init (struct tgl_state *TLS, char *M, tgl_peer_id_t to);
void tgp_msg_loading_free (gpointer data);
void tgp_msg_sending_free (gpointer data);
#endif