tAdd function to set curl callback functions - vaccinewars - be a doctor and try to vaccinate the world
 (HTM) git clone git://src.adamsgaard.dk/vaccinewars
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 7eb8e03609503bebc2e8364c8a69d975ea92d8e1
 (DIR) parent 81bdbf0ebfdca35cfde80dcc3a70911446234feb
 (HTM) Author: Ben Webb <ben@salilab.org>
       Date:   Thu,  5 Nov 2020 22:12:30 -0800
       
       Add function to set curl callback functions
       
       Diffstat:
         M src/gui_client/newgamedia.c         |     112 ++-----------------------------
         M src/network.c                       |      96 +++++++++++++++++++++++++++++++
         M src/network.h                       |      11 +++++++++++
       
       3 files changed, 113 insertions(+), 106 deletions(-)
       ---
 (DIR) diff --git a/src/gui_client/newgamedia.c b/src/gui_client/newgamedia.c
       t@@ -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");
       t@@ -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);
       t@@ -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;
       t@@ -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");
 (DIR) diff --git a/src/network.c b/src/network.c
       t@@ -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,
 (DIR) diff --git a/src/network.h b/src/network.h
       t@@ -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,
       t@@ -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,