Fix hang in socket closing.
* src/w32-io.c (destroy_reader): Call shutdown. (reader): Do not print an error in the shutdown case.
This commit is contained in:
parent
2118f49701
commit
9f330be821
36
src/w32-io.c
36
src/w32-io.c
@ -316,6 +316,21 @@ reader (void *arg)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Check whether the shutdown triggered the error -
|
||||||
|
no need to to print a warning in this case. */
|
||||||
|
if ( ctx->error_code == WSAECONNABORTED
|
||||||
|
|| ctx->error_code == WSAECONNRESET)
|
||||||
|
{
|
||||||
|
LOCK (ctx->mutex);
|
||||||
|
if (ctx->stop_me)
|
||||||
|
{
|
||||||
|
UNLOCK (ctx->mutex);
|
||||||
|
TRACE_LOG ("got shutdown");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
UNLOCK (ctx->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
ctx->error = 1;
|
ctx->error = 1;
|
||||||
TRACE_LOG1 ("recv error: ec=%d", ctx->error_code);
|
TRACE_LOG1 ("recv error: ec=%d", ctx->error_code);
|
||||||
}
|
}
|
||||||
@ -357,6 +372,7 @@ reader (void *arg)
|
|||||||
UNLOCK (ctx->mutex);
|
UNLOCK (ctx->mutex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE_LOG1 ("got %u bytes", nread);
|
TRACE_LOG1 ("got %u bytes", nread);
|
||||||
|
|
||||||
ctx->writepos = (ctx->writepos + nread) % READBUF_SIZE;
|
ctx->writepos = (ctx->writepos + nread) % READBUF_SIZE;
|
||||||
@ -495,6 +511,26 @@ destroy_reader (struct reader_context_s *ctx)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* The reader thread is usually blocking in recv or ReadFile. If
|
||||||
|
the peer does not send an EOF or breaks the pipe the WFSO might
|
||||||
|
get stuck waiting for the termination of the reader thread. This
|
||||||
|
happens quite often with sockets, thus we definitely need to get
|
||||||
|
out of the recv. A shutdown does this nicely. For handles
|
||||||
|
(i.e. pipes) it would also be nice to cancel the operation, but
|
||||||
|
such a feature is only available since Vista. Thus we need to
|
||||||
|
dlopen that syscall. */
|
||||||
|
if (ctx->file_hd != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
/* Fixme: Call CancelSynchronousIo (handle_of_thread). */
|
||||||
|
}
|
||||||
|
else if (ctx->file_sock != INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
if (shutdown (ctx->file_sock, 2))
|
||||||
|
TRACE2 (DEBUG_SYSIO, "gpgme:destroy_reader", ctx->file_hd,
|
||||||
|
"shutdown socket %d failed: %s",
|
||||||
|
ctx->file_sock, (int) WSAGetLastError ());
|
||||||
|
}
|
||||||
|
|
||||||
TRACE1 (DEBUG_SYSIO, "gpgme:destroy_reader", ctx->file_hd,
|
TRACE1 (DEBUG_SYSIO, "gpgme:destroy_reader", ctx->file_hd,
|
||||||
"waiting for termination of thread %p", ctx->thread_hd);
|
"waiting for termination of thread %p", ctx->thread_hd);
|
||||||
WaitForSingleObject (ctx->stopped, INFINITE);
|
WaitForSingleObject (ctx->stopped, INFINITE);
|
||||||
|
Loading…
Reference in New Issue
Block a user