mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-01 11:32:48 -05:00
Revamp net_pending_errors using toplevel callbacks.
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. [originally from svn r10023]
This commit is contained in:
@ -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 */
|
||||
|
@ -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.
|
||||
|
Reference in New Issue
Block a user