tGet notified of socket exceptions - 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 a5655b61d8f909d6e39939577b0dbd0347edb06d
 (DIR) parent 111a3e7ff7b73963eef8772ef30181c11bd9cd04
 (HTM) Author: Ben Webb <ben@salilab.org>
       Date:   Fri,  6 Nov 2020 01:04:08 -0800
       
       Get notified of socket exceptions
       
       Have glib notify us if our socket encounters an
       exception. This allows the GUI client to correctly
       report a connection failure on Mac.
       
       Diffstat:
         M src/gui_client/gtk_client.c         |      13 +++++++------
         M src/message.c                       |       6 ++++--
         M src/message.h                       |       3 ++-
         M src/network.c                       |       9 +++++----
         M src/network.h                       |       6 ++++--
         M src/serverside.c                    |      10 ++++++----
       
       6 files changed, 28 insertions(+), 19 deletions(-)
       ---
 (DIR) diff --git a/src/gui_client/gtk_client.c b/src/gui_client/gtk_client.c
       t@@ -108,7 +108,7 @@ static void UpdateMenus(void);
        static void GetClientMessage(gpointer data, gint socket,
                                     GdkInputCondition condition);
        void SocketStatus(NetworkBuffer *NetBuf, gboolean Read, gboolean Write,
       -                  gboolean CallNow);
       +                  gboolean Exception, gboolean CallNow);
        
        /* Data waiting to be sent to/read from the metaserver */
        CurlConnection MetaConn;
       t@@ -374,8 +374,8 @@ void GetClientMessage(gpointer data, gint socket,
        
          datawaiting =
              PlayerHandleNetwork(ClientData.Play, condition & GDK_INPUT_READ,
       -                          condition & GDK_INPUT_WRITE, &DoneOK);
       -
       +                          condition & GDK_INPUT_WRITE,
       +                          condition & GDK_INPUT_EXCEPTION, &DoneOK);
          status = NetBuf->status;
        
          /* Handle pre-game stuff */
       t@@ -408,15 +408,16 @@ void GetClientMessage(gpointer data, gint socket,
        }
        
        void SocketStatus(NetworkBuffer *NetBuf, gboolean Read, gboolean Write,
       -                  gboolean CallNow)
       +                  gboolean Exception, gboolean CallNow)
        {
          if (NetBuf->InputTag)
            gdk_input_remove(NetBuf->InputTag);
          NetBuf->InputTag = 0;
       -  if (Read || Write) {
       +  if (Read || Write || Exception) {
            NetBuf->InputTag = gdk_input_add(NetBuf->fd,
                                             (Read ? GDK_INPUT_READ : 0) |
       -                                     (Write ? GDK_INPUT_WRITE : 0),
       +                                     (Write ? GDK_INPUT_WRITE : 0) |
       +                                     (Exception ? GDK_INPUT_EXCEPTION : 0),
                                             GetClientMessage,
                                             NetBuf->CallBackData);
          }
 (DIR) diff --git a/src/message.c b/src/message.c
       t@@ -356,7 +356,8 @@ gboolean HaveAbility(Player *Play, gint Type)
         * unless a fatal error (i.e. the connection was broken) occurred.
         */
        gboolean PlayerHandleNetwork(Player *Play, gboolean ReadReady,
       -                             gboolean WriteReady, gboolean *DoneOK)
       +                             gboolean WriteReady, gboolean ErrorReady,
       +                             gboolean *DoneOK)
        {
          gboolean DataWaiting = FALSE;
        
       t@@ -364,7 +365,8 @@ gboolean PlayerHandleNetwork(Player *Play, gboolean ReadReady,
          if (!Play)
            return DataWaiting;
          DataWaiting =
       -      NetBufHandleNetwork(&Play->NetBuf, ReadReady, WriteReady, DoneOK);
       +      NetBufHandleNetwork(&Play->NetBuf, ReadReady, WriteReady, ErrorReady,
       +                          DoneOK);
        
          return DataWaiting;
        }
 (DIR) diff --git a/src/message.h b/src/message.h
       t@@ -87,7 +87,8 @@ typedef enum {
        GQuark dope_meta_error_quark(void);
        
        gboolean PlayerHandleNetwork(Player *Play, gboolean ReadReady,
       -                             gboolean WriteReady, gboolean *DoneOK);
       +                             gboolean WriteReady, gboolean ErrorReady,
       +                             gboolean *DoneOK);
        gboolean ReadPlayerDataFromWire(Player *Play);
        void QueuePlayerMessageForSend(Player *Play, gchar *data);
        gboolean WritePlayerDataToWire(Player *Play);
 (DIR) diff --git a/src/network.c b/src/network.c
       t@@ -155,14 +155,14 @@ static void NetBufCallBack(NetworkBuffer *NetBuf, gboolean CallNow)
                                  && NetBuf->WriteBuf.DataPresent)
                                 || (NetBuf->status == NBS_SOCKSCONNECT
                                     && NetBuf->negbuf.DataPresent)
       -                         || NetBuf->WaitConnect, CallNow);
       +                         || NetBuf->WaitConnect, TRUE, CallNow);
          }
        }
        
        static void NetBufCallBackStop(NetworkBuffer *NetBuf)
        {
          if (NetBuf && NetBuf->CallBack) {
       -    (*NetBuf->CallBack) (NetBuf, FALSE, FALSE, FALSE);
       +    (*NetBuf->CallBack) (NetBuf, FALSE, FALSE, FALSE, FALSE);
          }
        }
        
       t@@ -733,7 +733,8 @@ gboolean RespondToSelect(NetworkBuffer *NetBuf, fd_set *readfds,
        }
        
        gboolean NetBufHandleNetwork(NetworkBuffer *NetBuf, gboolean ReadReady,
       -                             gboolean WriteReady, gboolean *DoneOK)
       +                             gboolean WriteReady, gboolean ErrorReady,
       +                             gboolean *DoneOK)
        {
          gboolean ReadOK, WriteOK, ErrorOK;
          gboolean DataWaiting = FALSE;
       t@@ -742,7 +743,7 @@ gboolean NetBufHandleNetwork(NetworkBuffer *NetBuf, gboolean ReadReady,
          if (!NetBuf || NetBuf->fd <= 0)
            return DataWaiting;
        
       -  DataWaiting = DoNetworkBufferStuff(NetBuf, ReadReady, WriteReady, FALSE,
       +  DataWaiting = DoNetworkBufferStuff(NetBuf, ReadReady, WriteReady, ErrorReady,
                                             &ReadOK, &WriteOK, &ErrorOK);
        
          *DoneOK = (WriteOK && ErrorOK && ReadOK);
 (DIR) diff --git a/src/network.h b/src/network.h
       t@@ -86,7 +86,8 @@ typedef struct _ConnBuf {
        typedef struct _NetworkBuffer NetworkBuffer;
        
        typedef void (*NBCallBack) (NetworkBuffer *NetBuf, gboolean Read,
       -                            gboolean Write, gboolean CallNow);
       +                            gboolean Write, gboolean Exception,
       +                            gboolean CallNow);
        
        typedef void (*NBUserPasswd) (NetworkBuffer *NetBuf, gpointer data);
        
       t@@ -216,7 +217,8 @@ gboolean RespondToSelect(NetworkBuffer *NetBuf, fd_set *readfds,
                                 fd_set *writefds, fd_set *errorfds,
                                 gboolean *DoneOK);
        gboolean NetBufHandleNetwork(NetworkBuffer *NetBuf, gboolean ReadReady,
       -                             gboolean WriteReady, gboolean *DoneOK);
       +                             gboolean WriteReady, gboolean ErrorReady,
       +                             gboolean *DoneOK);
        gboolean ReadDataFromWire(NetworkBuffer *NetBuf);
        gboolean WriteDataToWire(NetworkBuffer *NetBuf);
        void QueueMessageForSend(NetworkBuffer *NetBuf, gchar *data);
 (DIR) diff --git a/src/serverside.c b/src/serverside.c
       t@@ -1364,7 +1364,7 @@ void ServerLoop(struct CMDLINE *cmdline)
        static GtkWidget *TextOutput;
        static gint ListenTag = 0;
        static void SocketStatus(NetworkBuffer *NetBuf, gboolean Read,
       -                         gboolean Write, gboolean CallNow);
       +                         gboolean Write, gboolean Exception, gboolean CallNow);
        static void GuiSetTimeouts(void);
        static time_t NextTimeout = 0;
        static guint TimeoutTag = 0;
       t@@ -1461,7 +1461,8 @@ static void GuiHandleSocket(gpointer data, gint socket,
            return;
        
          if (PlayerHandleNetwork(Play, condition & GDK_INPUT_READ,
       -                          condition & GDK_INPUT_WRITE, &DoneOK)) {
       +                          condition & GDK_INPUT_WRITE,
       +                          condition & GDK_INPUT_EXCEPTION, &DoneOK)) {
            HandleServerPlayer(Play);
            GuiSetTimeouts();           /* We may have set some new timeouts */
          }
       t@@ -1473,7 +1474,7 @@ static void GuiHandleSocket(gpointer data, gint socket,
        }
        
        void SocketStatus(NetworkBuffer *NetBuf, gboolean Read, gboolean Write,
       -                  gboolean CallNow)
       +                  gboolean Exception, gboolean CallNow)
        {
          if (NetBuf->InputTag)
            gdk_input_remove(NetBuf->InputTag);
       t@@ -1481,7 +1482,8 @@ void SocketStatus(NetworkBuffer *NetBuf, gboolean Read, gboolean Write,
          if (Read || Write) {
            NetBuf->InputTag = gdk_input_add(NetBuf->fd,
                                             (Read ? GDK_INPUT_READ : 0) |
       -                                     (Write ? GDK_INPUT_WRITE : 0),
       +                                     (Write ? GDK_INPUT_WRITE : 0) |
       +                                     (Exception ? GDK_INPUT_EXCEPTION : 0),
                                             GuiHandleSocket,
                                             NetBuf->CallBackData);
          }