w32: Fix closing file descriptors.

* src/w32-io.c (writer): Only stop once the buffer is drained.
(destroy_writer): Wait for the writers buffer to be drained.  This
aligns '_gpgme_io_close's behavior with close(2) and fclose(3).

GnuPG-bug-id: 2881
Signed-off-by: Justus Winter <justus@g10code.com>
This commit is contained in:
Justus Winter 2017-01-23 15:08:23 +01:00
parent ca69df8c8d
commit 6f02133bb0

View File

@ -700,7 +700,7 @@ writer (void *arg)
for (;;) for (;;)
{ {
LOCK (ctx->mutex); LOCK (ctx->mutex);
if (ctx->stop_me) if (ctx->stop_me && !ctx->nbytes)
{ {
UNLOCK (ctx->mutex); UNLOCK (ctx->mutex);
break; break;
@ -717,7 +717,7 @@ writer (void *arg)
TRACE_LOG ("got data to send"); TRACE_LOG ("got data to send");
LOCK (ctx->mutex); LOCK (ctx->mutex);
} }
if (ctx->stop_me) if (ctx->stop_me && !ctx->nbytes)
{ {
UNLOCK (ctx->mutex); UNLOCK (ctx->mutex);
break; break;
@ -776,6 +776,9 @@ writer (void *arg)
TRACE_LOG ("waiting for close"); TRACE_LOG ("waiting for close");
WaitForSingleObject (ctx->close_ev, INFINITE); WaitForSingleObject (ctx->close_ev, INFINITE);
if (ctx->nbytes)
TRACE_LOG1 ("still %d bytes in buffer at close time", ctx->nbytes);
CloseHandle (ctx->close_ev); CloseHandle (ctx->close_ev);
CloseHandle (ctx->have_data); CloseHandle (ctx->have_data);
CloseHandle (ctx->is_empty); CloseHandle (ctx->is_empty);
@ -892,6 +895,9 @@ destroy_writer (struct writer_context_s *ctx)
SetEvent (ctx->have_data); SetEvent (ctx->have_data);
UNLOCK (ctx->mutex); UNLOCK (ctx->mutex);
/* Give the writer a chance to flush the buffer. */
WaitForSingleObject (ctx->is_empty, INFINITE);
#ifdef HAVE_W32CE_SYSTEM #ifdef HAVE_W32CE_SYSTEM
/* Scenario: We never create a full pipe, but already started /* Scenario: We never create a full pipe, but already started
writing more than the pipe buffer. Then we need to unblock the writing more than the pipe buffer. Then we need to unblock the