/* Data received from stderr_H, if we have one. */
bufchain stderrdata;
+ int defer_close, deferred_close; /* in case of re-entrance */
+
char *error;
Plug plug;
} else if (len == 0) {
return plug_closing(ps->plug, NULL, 0, 0);
} else {
- assert(ps->frozen != FREEZING && ps->frozen != THAWING);
+ assert(ps->frozen != FROZEN && ps->frozen != THAWING);
if (ps->frozen == FREEZING) {
/*
* If we've received data while this socket is supposed to
* the data for when we unfreeze.
*/
bufchain_add(&ps->inputdata, data, len);
+ ps->frozen = FROZEN;
/*
* And return a very large backlog, to prevent further
{
Handle_Socket ps = (Handle_Socket) s;
+ if (ps->defer_close) {
+ ps->deferred_close = TRUE;
+ return;
+ }
+
handle_free(ps->send_h);
handle_free(ps->recv_h);
CloseHandle(ps->send_H);
assert(len > 0);
/*
- * Hand it off to the plug.
+ * Hand it off to the plug. Be careful of re-entrance - that might
+ * have the effect of trying to close this socket.
*/
+ ps->defer_close = TRUE;
new_backlog = plug_receive(ps->plug, 0, data, len);
+ bufchain_consume(&ps->inputdata, len);
+ ps->defer_close = FALSE;
+ if (ps->deferred_close) {
+ sk_handle_close(ps);
+ return;
+ }
if (bufchain_size(&ps->inputdata) > 0) {
/*
ret->stderr_h = handle_input_new(ret->stderr_H, handle_stderr,
ret, flags);
+ ret->defer_close = ret->deferred_close = FALSE;
+
return (Socket) ret;
}