]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - windows/winnet.c
Revamp net_pending_errors using toplevel callbacks.
[PuTTY.git] / windows / winnet.c
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.