]> asedeno.scripts.mit.edu Git - PuTTY_svn.git/commitdiff
Revamp net_pending_errors using toplevel callbacks.
authorSimon Tatham <anakin@pobox.com>
Sat, 17 Aug 2013 16:06:27 +0000 (16:06 +0000)
committerSimon Tatham <anakin@pobox.com>
Sat, 17 Aug 2013 16:06:27 +0000 (16:06 +0000)
Again, I've removed the special-purpose ad-hockery from the assorted
front end message loops that dealt with deferred handling of socket
errors, and instead uxnet.c and winnet.c arrange that for themselves
by calling the new general top-level callback mechanism.

git-svn-id: http://svn.tartarus.org/sgt/putty@10023 cda61777-01e9-0310-a592-d414129be87e

network.h
unix/gtkwin.c
unix/unix.h
unix/uxnet.c
unix/uxplink.c
unix/uxpterm.c
windows/window.c
windows/winnet.c

index b432ccae4918b7c7d635528ea0e76535f02bb8fe..f390a5d0eb1013bec752c0836de2156df2c0c713 100644 (file)
--- a/network.h
+++ b/network.h
@@ -190,12 +190,6 @@ const char *sk_addr_error(SockAddr addr);
  */
 #define sk_set_frozen(s, is_frozen) (((*s)->set_frozen) (s, is_frozen))
 
-/*
- * Call this after an operation that might have tried to send on a
- * socket, to clean up any pending network errors.
- */
-void net_pending_errors(void);
-
 /*
  * Simple wrapper on getservbyname(), needed by ssh.c. Returns the
  * port number, in host byte order (suitable for printf and so on).
index 7bc41cc936d1d0eaaae0cce1d2e92f4bfa53c6f8..59a5c383a8f8c4d0f272cfd0d2b4694b02cf95a1 100644 (file)
@@ -2843,24 +2843,6 @@ void uxsel_input_remove(int id) {
     gdk_input_remove(id);
 }
 
-int frontend_net_pending_error_idle_id;
-int frontend_got_net_pending_errors = FALSE;
-gboolean frontend_net_pending_errors(gpointer data)
-{
-    net_pending_errors();
-    gtk_idle_remove(frontend_net_pending_error_idle_id);
-    frontend_got_net_pending_errors = FALSE;
-    return FALSE;
-}
-void frontend_net_error_pending(void)
-{
-    if (!frontend_got_net_pending_errors) {
-        frontend_got_net_pending_errors = TRUE;
-        frontend_net_pending_error_idle_id =
-            gtk_idle_add(frontend_net_pending_errors, NULL);
-    }
-}
-
 char *setup_fonts_ucs(struct gui_data *inst)
 {
     int shadowbold = conf_get_int(inst->conf, CONF_shadowbold);
index a9f00bf2d3f89a20c407c278e69d128fbabcd298..c2f9aeb1c3a7b6045aaf5451af7afa7cc3c95068 100644 (file)
@@ -173,13 +173,6 @@ int init_ucs(struct unicode_data *ucsdata, char *line_codepage,
  */
 void *sk_getxdmdata(void *sock, int *lenp);
 
-/*
- * Function provided by front ends, and called by uxnet.c to indicate
- * that net_pending_errors() would like to be called back when the
- * front end has a spare moment and isn't deep in any other recursion.
- */
-void frontend_net_error_pending(void);
-
 /*
  * General helpful Unix stuff: more helpful version of the FD_SET
  * macro, which also handles maxfd.
index d8460c19aa67fe8aca2be3e32a3392a06e94c6e6..9fc649f75d6392a7f3451cba1b089c6f96074058 100644 (file)
@@ -1025,6 +1025,26 @@ void *sk_getxdmdata(void *sock, int *lenp)
     return buf;
 }
 
+/*
+ * Deal with socket errors detected in try_send().
+ */
+static void socket_error_callback(void *vs)
+{
+    Actual_Socket s = (Actual_Socket)vs;
+
+    /*
+     * Just in case other socket work has caused this socket to vanish
+     * or become somehow non-erroneous before this callback arrived...
+     */
+    if (!find234(sktree, s, NULL) || !s->pending_error)
+        return;
+
+    /*
+     * An error has occurred on this socket. Pass it to the plug.
+     */
+    plug_closing(s->plug, strerror(s->pending_error), s->pending_error, 0);
+}
+
 /*
  * The function which tries to send on a socket once it's deemed
  * writable.
@@ -1073,9 +1093,10 @@ void try_send(Actual_Socket s)
                  */
                 uxsel_tell(s);
                 /*
-                 * Notify the front end that it might want to call us.
+                 * Arrange to be called back from the top level to
+                 * deal with the error condition on this socket.
                  */
-                frontend_net_error_pending();
+                queue_toplevel_callback(socket_error_callback, s);
                return;
            }
        } else {
@@ -1352,43 +1373,6 @@ static int net_select_result(int fd, int event)
     return 1;
 }
 
-/*
- * Deal with socket errors detected in try_send().
- */
-void net_pending_errors(void)
-{
-    int i;
-    Actual_Socket s;
-
-    /*
-     * This might be a fiddly business, because it's just possible
-     * that handling a pending error on one socket might cause
-     * others to be closed. (I can't think of any reason this might
-     * happen in current SSH implementation, but to maintain
-     * generality of this network layer I'll assume the worst.)
-     * 
-     * So what we'll do is search the socket list for _one_ socket
-     * with a pending error, and then handle it, and then search
-     * the list again _from the beginning_. Repeat until we make a
-     * pass with no socket errors present. That way we are
-     * protected against the socket list changing under our feet.
-     */
-
-    do {
-       for (i = 0; (s = index234(sktree, i)) != NULL; i++) {
-           if (s->pending_error) {
-               /*
-                * An error has occurred on this socket. Pass it to the
-                * plug.
-                */
-               plug_closing(s->plug, strerror(s->pending_error),
-                            s->pending_error, 0);
-               break;
-           }
-       }
-    } while (s);
-}
-
 /*
  * Each socket abstraction contains a `void *' private field in
  * which the client can keep state.
index 36f3e2fce88cc8403a5944e8c7e7b06fb5b16945..85f91224d6d3a927969f784ce943587760ae801e 100644 (file)
@@ -1116,8 +1116,6 @@ int main(int argc, char **argv)
            back->unthrottle(backhandle, try_output(TRUE));
        }
 
-        net_pending_errors();
-
         run_toplevel_callbacks();
 
        if ((!connopen || !back->connected(backhandle)) &&
index 6542fbbaf4180df75f4b50f89d1f930e63feb38f..1f4f20c2aaf363c32a1e2ec4e24d6649ccf1518c 100644 (file)
@@ -17,16 +17,6 @@ Backend *select_backend(Conf *conf)
     return &pty_backend;
 }
 
-void net_pending_errors(void)
-{
-    /*
-     * Stub version of net_pending_errors(), because gtkwin.c has to
-     * be prepared to call it when linked into PuTTY and therefore we
-     * have to avoid a link failure when linking gtkwin.c in turn into
-     * a non-networked application.
-     */
-}
-
 int cfgbox(Conf *conf)
 {
     /*
index 77e4e9eb61f729998869a8a184b00aa4abcafa86..b5a18e5af1d6cc5ea378c799e0d25a774f50d7d2 100644 (file)
@@ -874,8 +874,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
 
        if (pending_netevent)
            enact_pending_netevent();
-
-       net_pending_errors();
     }
 
     finished:
@@ -2349,7 +2347,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
 
                InvalidateRect(hwnd, NULL, TRUE);
                reset_window(init_lvl);
-               net_pending_errors();
 
                conf_free(prev_conf);
            }
@@ -2412,7 +2409,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
                    break;
                if (back)
                    back->special(backhandle, specials[i].code);
-               net_pending_errors();
            }
        }
        break;
@@ -2705,7 +2701,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
        if (WSAGETSELECTEVENT(lParam) != FD_READ)
            enact_pending_netevent();
 
-       net_pending_errors();
        return 0;
       case WM_SETFOCUS:
        term_set_focus(term, TRUE);
@@ -3087,7 +3082,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
                }
            }
        }
-       net_pending_errors();
        return 0;
       case WM_INPUTLANGCHANGE:
        /* wParam == Font number */
index 4fddd72c013740e1c469eec0974be79206647adc..00a8290d1a8b82a06b616c0c69a589b968d70551 100644 (file)
@@ -1345,6 +1345,26 @@ static void sk_tcp_close(Socket sock)
     sfree(s);
 }
 
+/*
+ * Deal with socket errors detected in try_send().
+ */
+static void socket_error_callback(void *vs)
+{
+    Actual_Socket s = (Actual_Socket)vs;
+
+    /*
+     * Just in case other socket work has caused this socket to vanish
+     * or become somehow non-erroneous before this callback arrived...
+     */
+    if (!find234(sktree, s, NULL) || !s->pending_error)
+        return;
+
+    /*
+     * An error has occurred on this socket. Pass it to the plug.
+     */
+    plug_closing(s->plug, strerror(s->pending_error), s->pending_error, 0);
+}
+
 /*
  * The function which tries to send on a socket once it's deemed
  * writable.
@@ -1394,6 +1414,7 @@ void try_send(Actual_Socket s)
                 * plug_closing()) at some suitable future moment.
                 */
                s->pending_error = err;
+                queue_toplevel_callback(socket_error_callback, s);
                return;
            } else {
                /* We're inside the Windows frontend here, so we know
@@ -1666,44 +1687,6 @@ int select_result(WPARAM wParam, LPARAM lParam)
     return 1;
 }
 
-/*
- * Deal with socket errors detected in try_send().
- */
-void net_pending_errors(void)
-{
-    int i;
-    Actual_Socket s;
-
-    /*
-     * This might be a fiddly business, because it's just possible
-     * that handling a pending error on one socket might cause
-     * others to be closed. (I can't think of any reason this might
-     * happen in current SSH implementation, but to maintain
-     * generality of this network layer I'll assume the worst.)
-     * 
-     * So what we'll do is search the socket list for _one_ socket
-     * with a pending error, and then handle it, and then search
-     * the list again _from the beginning_. Repeat until we make a
-     * pass with no socket errors present. That way we are
-     * protected against the socket list changing under our feet.
-     */
-
-    do {
-       for (i = 0; (s = index234(sktree, i)) != NULL; i++) {
-           if (s->pending_error) {
-               /*
-                * An error has occurred on this socket. Pass it to the
-                * plug.
-                */
-               plug_closing(s->plug,
-                            winsock_error_string(s->pending_error),
-                            s->pending_error, 0);
-               break;
-           }
-       }
-    } while (s);
-}
-
 /*
  * Each socket abstraction contains a `void *' private field in
  * which the client can keep state.