vaccinewars

be a doctor and try to vaccinate the world
git clone git://src.adamsgaard.dk/vaccinewars # fast
git clone https://src.adamsgaard.dk/vaccinewars.git # slow
Log | Files | Refs | README | LICENSE Back to index

commit 7eb8e03609503bebc2e8364c8a69d975ea92d8e1
parent 81bdbf0ebfdca35cfde80dcc3a70911446234feb
Author: Ben Webb <ben@salilab.org>
Date:   Thu,  5 Nov 2020 22:12:30 -0800

Add function to set curl callback functions

Diffstat:
Msrc/gui_client/newgamedia.c | 112+++++--------------------------------------------------------------------------
Msrc/network.c | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/network.h | 11+++++++++++
3 files changed, 113 insertions(+), 106 deletions(-)

diff --git a/src/gui_client/newgamedia.c b/src/gui_client/newgamedia.c @@ -83,30 +83,13 @@ static void SetStartGameStatus(gchar *msg) #ifdef NETWORKING -/* Global information, common to all connections */ -typedef struct _GlobalData { - CURLM *multi; - guint timer_event; - int still_running; -} GlobalData; - -/* Information associated with a specific socket */ -typedef struct _SockData { - curl_socket_t sockfd; - CURL *easy; - int action; - long timeout; - GIOChannel *ch; - guint ev; - GlobalData *global; -} SockData; - -GlobalData global_data; +CurlGlobalData global_data; /* Called by glib when we get action on a multi socket */ -static gboolean glib_socket(GIOChannel *ch, GIOCondition condition, gpointer data) +static gboolean glib_socket(GIOChannel *ch, GIOCondition condition, + gpointer data) { - GlobalData *g = (GlobalData*) data; + CurlGlobalData *g = (CurlGlobalData*) data; CURLMcode rc; int fd = g_io_channel_unix_get_fd(ch); fprintf(stderr, "bw> glib socket\n"); @@ -144,7 +127,7 @@ static gboolean glib_socket(GIOChannel *ch, GIOCondition condition, gpointer dat static gboolean glib_timeout(gpointer userp) { - GlobalData *g = userp; + CurlGlobalData *g = userp; CURLMcode rc; fprintf(stderr, "bw> glib_timeout\n"); rc = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0, &g->still_running); @@ -153,83 +136,6 @@ static gboolean glib_timeout(gpointer userp) return G_SOURCE_REMOVE; } -int timer_cb(CURLM *multi, long timeout_ms, void *userp) -{ - fprintf(stderr, "bw> timer_cb %ld\n", timeout_ms); - GlobalData *g = userp; - - if (g->timer_event) { - g_source_remove(g->timer_event); - g->timer_event = 0; - } - - /* -1 means we should just delete our timer. */ - if (timeout_ms >= 0) { - g->timer_event = g_timeout_add(timeout_ms, glib_timeout, g); - } - return 0; -} - -/* Clean up the SockData structure */ -static void remsock(SockData *f) -{ - if (!f) { - return; - } - if (f->ev) { - g_source_remove(f->ev); - } - g_free(f); -} - -/* Assign information to a SockData structure */ -static void setsock(SockData *f, curl_socket_t s, CURL *e, int act, - GlobalData *g) -{ - GIOCondition kind = - ((act & CURL_POLL_IN) ? G_IO_IN : 0) | - ((act & CURL_POLL_OUT) ? G_IO_OUT : 0); - - f->sockfd = s; - f->action = act; - f->easy = e; - if (f->ev) { - g_source_remove(f->ev); - } - f->ev = g_io_add_watch(f->ch, kind, glib_socket, g); -} - -/* Initialize a new SockData structure */ -static void addsock(curl_socket_t s, CURL *easy, int action, GlobalData *g) -{ - SockData *fdp = g_malloc0(sizeof(SockData)); - - fdp->global = g; - fdp->ch = g_io_channel_unix_new(s); - setsock(fdp, s, easy, action, g); - curl_multi_assign(g->multi, s, fdp); -} - -int socket_cb(CURL *easy, curl_socket_t s, int what, void *userp, - void *socketp) -{ - GlobalData *g = userp; - SockData *fdp = socketp; - static const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" }; - fprintf(stderr, "bw> socket_cb s=%d %d what=%s\n", s, what, whatstr[what]); - if (what == CURL_POLL_REMOVE) { - fprintf(stderr, "remove socket\n"); - remsock(fdp); - } else if (!fdp) { - fprintf(stderr, "add socket\n"); - addsock(s, easy, what, g); - } else { - fprintf(stderr, "change socket\n"); - setsock(fdp, s, easy, what, g); - } - return 0; -} - static void ConnectError(gboolean meta) { GString *neterr; @@ -525,16 +431,10 @@ void NewGameDialog(Player *play) guint AccelKey; #ifdef NETWORKING - global_data.multi = MetaConn->multi; - global_data.timer_event = 0; GtkWidget *clist, *scrollwin, *table, *hbbox; gchar *server_titles[5], *ServerEntry, *text; gboolean UpdateMeta = FALSE; - - curl_multi_setopt(MetaConn->multi, CURLMOPT_TIMERFUNCTION, timer_cb); - curl_multi_setopt(MetaConn->multi, CURLMOPT_TIMERDATA, &global_data); - curl_multi_setopt(MetaConn->multi, CURLMOPT_SOCKETFUNCTION, socket_cb); - curl_multi_setopt(MetaConn->multi, CURLMOPT_SOCKETDATA, &global_data); + SetCurlCallback(MetaConn, &global_data, glib_timeout, glib_socket); /* Column titles of metaserver information */ server_titles[0] = _("Server"); diff --git a/src/network.c b/src/network.c @@ -1370,6 +1370,102 @@ char *CurlNextLine(CurlConnection *conn, char *ch) return sep_pt; } +/* Information associated with a specific socket */ +typedef struct _SockData { + curl_socket_t sockfd; + CURL *easy; + int action; + long timeout; + GIOChannel *ch; + guint ev; + CurlGlobalData *global; +} SockData; + +static int timer_function(CURLM *multi, long timeout_ms, void *userp) +{ + CurlGlobalData *g = userp; + + if (g->timer_event) { + g_source_remove(g->timer_event); + g->timer_event = 0; + } + + /* -1 means we should just delete our timer. */ + if (timeout_ms >= 0) { + g->timer_event = g_timeout_add(timeout_ms, g->timer_cb, g); + } + return 0; +} + +/* Clean up the SockData structure */ +static void remsock(SockData *f) +{ + if (!f) { + return; + } + if (f->ev) { + g_source_remove(f->ev); + } + g_free(f); +} + +/* Assign information to a SockData structure */ +static void setsock(SockData *f, curl_socket_t s, CURL *e, int act, + CurlGlobalData *g) +{ + GIOCondition kind = + ((act & CURL_POLL_IN) ? G_IO_IN : 0) | + ((act & CURL_POLL_OUT) ? G_IO_OUT : 0); + + f->sockfd = s; + f->action = act; + f->easy = e; + if (f->ev) { + g_source_remove(f->ev); + } + f->ev = g_io_add_watch(f->ch, kind, g->socket_cb, g); +} + +/* Initialize a new SockData structure */ +static void addsock(curl_socket_t s, CURL *easy, int action, CurlGlobalData *g) +{ + SockData *fdp = g_malloc0(sizeof(SockData)); + + fdp->global = g; + fdp->ch = g_io_channel_unix_new(s); + setsock(fdp, s, easy, action, g); + curl_multi_assign(g->multi, s, fdp); +} + +static int socket_function(CURL *easy, curl_socket_t s, int what, void *userp, + void *socketp) +{ + CurlGlobalData *g = userp; + SockData *fdp = socketp; + if (what == CURL_POLL_REMOVE) { + remsock(fdp); + } else if (!fdp) { + addsock(s, easy, what, g); + } else { + setsock(fdp, s, easy, what, g); + } + return 0; +} + +void SetCurlCallback(CurlConnection *conn, CurlGlobalData *g, + GSourceFunc timer_cb, GIOFunc socket_cb) +{ + g->multi = conn->multi; + g->timer_event = 0; + g->timer_cb = timer_cb; + g->socket_cb = socket_cb; + + curl_multi_setopt(g->multi, CURLMOPT_TIMERFUNCTION, timer_function); + curl_multi_setopt(g->multi, CURLMOPT_TIMERDATA, g); + curl_multi_setopt(g->multi, CURLMOPT_SOCKETFUNCTION, socket_function); + curl_multi_setopt(g->multi, CURLMOPT_SOCKETDATA, g); +} + gboolean OpenHttpConnection(HttpConnection **connpt, gchar *HostName, unsigned Port, gchar *Proxy, unsigned ProxyPort, const gchar *bindaddr, diff --git a/src/network.h b/src/network.h @@ -232,6 +232,15 @@ GQuark dope_curl_error_quark(void); #define DOPE_CURLM_ERROR dope_curlm_error_quark() GQuark dope_curlm_error_quark(void); +/* Global information, common to all connections */ +typedef struct _CurlGlobalData { + CURLM *multi; + guint timer_event; + int still_running; + GSourceFunc timer_cb; + GIOFunc socket_cb; +} CurlGlobalData; + void CurlInit(CurlConnection *conn); void CurlCleanup(CurlConnection *conn); gboolean OpenCurlConnection(CurlConnection *conn, char *URL, char *body, @@ -240,6 +249,8 @@ void CloseCurlConnection(CurlConnection *conn); gboolean CurlConnectionPerform(CurlConnection *conn, int *still_running, GError **err); char *CurlNextLine(CurlConnection *conn, char *ch); +void SetCurlCallback(CurlConnection *conn, CurlGlobalData *g, + GSourceFunc timer_cb, GIOFunc socket_cb); gboolean OpenHttpConnection(HttpConnection **conn, gchar *HostName, unsigned Port, gchar *Proxy,