*/
#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).
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);
*/
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.
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.
*/
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 {
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.
back->unthrottle(backhandle, try_output(TRUE));
}
- net_pending_errors();
-
run_toplevel_callbacks();
if ((!connopen || !back->connected(backhandle)) &&
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)
{
/*
if (pending_netevent)
enact_pending_netevent();
-
- net_pending_errors();
}
finished:
InvalidateRect(hwnd, NULL, TRUE);
reset_window(init_lvl);
- net_pending_errors();
conf_free(prev_conf);
}
break;
if (back)
back->special(backhandle, specials[i].code);
- net_pending_errors();
}
}
break;
if (WSAGETSELECTEVENT(lParam) != FD_READ)
enact_pending_netevent();
- net_pending_errors();
return 0;
case WM_SETFOCUS:
term_set_focus(term, TRUE);
}
}
}
- net_pending_errors();
return 0;
case WM_INPUTLANGCHANGE:
/* wParam == Font number */
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.
* 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
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.