Skip to content
Snippets Groups Projects
Commit c2c4ab93 authored by Armin Luntzer's avatar Armin Luntzer
Browse files

server net: more reference counting, more locking

parent fce8bd55
No related branches found
No related tags found
No related merge requests found
...@@ -109,6 +109,7 @@ static gboolean net_push_userlist_cb(gpointer data) ...@@ -109,6 +109,7 @@ static gboolean net_push_userlist_cb(gpointer data)
gchar *msg = NULL; gchar *msg = NULL;
g_mutex_lock(&listlock);
for (elem = con_list; elem; elem = elem->next) { for (elem = con_list; elem; elem = elem->next) {
...@@ -146,6 +147,8 @@ static gboolean net_push_userlist_cb(gpointer data) ...@@ -146,6 +147,8 @@ static gboolean net_push_userlist_cb(gpointer data)
g_free(msg); g_free(msg);
} }
g_mutex_unlock(&listlock);
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
...@@ -223,6 +226,8 @@ static void drop_con_begin(struct con_data *c) ...@@ -223,6 +226,8 @@ static void drop_con_begin(struct con_data *c)
/** /**
* @brief finalize a connection drop * @brief finalize a connection drop
*
* @note the connection must already be removed from con_list at this point!
*/ */
static void drop_con_finalize(struct con_data *c) static void drop_con_finalize(struct con_data *c)
...@@ -230,13 +235,20 @@ static void drop_con_finalize(struct con_data *c) ...@@ -230,13 +235,20 @@ static void drop_con_finalize(struct con_data *c)
gchar *buf; gchar *buf;
g_mutex_lock(&listlock); if (!c) {
g_warning("c is NULL");
return;
}
if (!c->con) if (!c->con) {
goto exit; g_warning("c->con is NULL");
return;
}
if (G_IS_OBJECT(c->con)) if (G_IS_OBJECT(c->con)) {
goto exit; g_warning("c->con still holds references");
return;
}
if (c->kick) { if (c->kick) {
buf = g_strdup_printf("I kicked <tt><span foreground='#F1C40F'>" buf = g_strdup_printf("I kicked <tt><span foreground='#F1C40F'>"
...@@ -263,10 +275,6 @@ static void drop_con_finalize(struct con_data *c) ...@@ -263,10 +275,6 @@ static void drop_con_finalize(struct con_data *c)
g_free(buf); g_free(buf);
g_free(c); g_free(c);
exit:
g_mutex_unlock(&listlock);
} }
...@@ -517,6 +525,9 @@ drop_pkt: ...@@ -517,6 +525,9 @@ drop_pkt:
g_free(pkt); g_free(pkt);
ret = g_buffered_input_stream_fill_finish(bistream, res, &error); ret = g_buffered_input_stream_fill_finish(bistream, res, &error);
g_object_unref(c->con);
if (ret < 0) if (ret < 0)
goto error; goto error;
...@@ -531,6 +542,8 @@ exit: ...@@ -531,6 +542,8 @@ exit:
if (!G_IS_OBJECT(c->con)) if (!G_IS_OBJECT(c->con))
return; return;
g_object_ref(c->con);
/* continue buffering */ /* continue buffering */
g_buffered_input_stream_fill_async(bistream, g_buffered_input_stream_fill_async(bistream,
g_buffered_input_stream_get_buffer_size(bistream), g_buffered_input_stream_get_buffer_size(bistream),
...@@ -551,6 +564,9 @@ error: ...@@ -551,6 +564,9 @@ error:
} }
drop_con_begin(c); drop_con_begin(c);
/* if this was the last reference, call finalize */
if (!G_IS_OBJECT(c->con))
drop_con_finalize(c); drop_con_finalize(c);
return; return;
...@@ -571,6 +587,8 @@ static void assign_default_priv(struct con_data *c) ...@@ -571,6 +587,8 @@ static void assign_default_priv(struct con_data *c)
struct con_data *item; struct con_data *item;
g_mutex_lock(&listlock);
for (elem = con_list; elem; elem = elem->next) { for (elem = con_list; elem; elem = elem->next) {
item = (struct con_data *) elem->data; item = (struct con_data *) elem->data;
...@@ -581,6 +599,8 @@ static void assign_default_priv(struct con_data *c) ...@@ -581,6 +599,8 @@ static void assign_default_priv(struct con_data *c)
if (!priv) if (!priv)
c->priv = TRUE; c->priv = TRUE;
g_mutex_unlock(&listlock);
} }
...@@ -602,6 +622,8 @@ static void begin_reception(struct con_data *c) ...@@ -602,6 +622,8 @@ static void begin_reception(struct con_data *c)
bistream = G_BUFFERED_INPUT_STREAM(c->istream); bistream = G_BUFFERED_INPUT_STREAM(c->istream);
bufsize = g_buffered_input_stream_get_buffer_size(bistream); bufsize = g_buffered_input_stream_get_buffer_size(bistream);
g_object_ref(c->con);
g_buffered_input_stream_fill_async(bistream, bufsize, g_buffered_input_stream_fill_async(bistream, bufsize,
G_PRIORITY_DEFAULT, c->ca, G_PRIORITY_DEFAULT, c->ca,
net_buffer_ready, c); net_buffer_ready, c);
...@@ -718,6 +740,8 @@ gint net_send(const char *pkt, gsize nbytes) ...@@ -718,6 +740,8 @@ gint net_send(const char *pkt, gsize nbytes)
g_mutex_lock(&netlock_big); g_mutex_lock(&netlock_big);
g_mutex_lock(&listlock);
for (elem = con_list; elem; elem = elem->next) { for (elem = con_list; elem; elem = elem->next) {
c = (struct con_data *) elem->data; c = (struct con_data *) elem->data;
...@@ -726,7 +750,6 @@ gint net_send(const char *pkt, gsize nbytes) ...@@ -726,7 +750,6 @@ gint net_send(const char *pkt, gsize nbytes)
continue; continue;
if (c->kick) { if (c->kick) {
drop = c; drop = c;
continue; continue;
} }
...@@ -734,8 +757,12 @@ gint net_send(const char *pkt, gsize nbytes) ...@@ -734,8 +757,12 @@ gint net_send(const char *pkt, gsize nbytes)
ret |= net_send_single(c, pkt, nbytes); ret |= net_send_single(c, pkt, nbytes);
} }
g_mutex_unlock(&listlock);
/* drop one per cycle */
if (drop) if (drop)
drop_con_begin(drop); drop_con_begin(drop);
g_mutex_unlock(&netlock_big); g_mutex_unlock(&netlock_big);
return ret; return ret;
...@@ -758,10 +785,12 @@ void net_server_reassign_control(gpointer ref) ...@@ -758,10 +785,12 @@ void net_server_reassign_control(gpointer ref)
c = (struct con_data *) ref; c = (struct con_data *) ref;
g_mutex_lock(&listlock);
for (elem = con_list; elem; elem = elem->next) { for (elem = con_list; elem; elem = elem->next) {
item = (struct con_data *) elem->data; item = (struct con_data *) elem->data;
item->priv = FALSE; item->priv = FALSE;
} }
g_mutex_unlock(&listlock);
c->priv = TRUE; c->priv = TRUE;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment