diff options
| author | Werner Koch <[email protected]> | 2013-04-25 11:00:16 +0000 | 
|---|---|---|
| committer | Werner Koch <[email protected]> | 2013-05-08 18:38:50 +0000 | 
| commit | 9f330be8210d2498fe93d4166b6f6c02fca76475 (patch) | |
| tree | 1874cdd0303cacfc7afa3ec77d397939a70162a1 | |
| parent | Improve debug output of the I/O reader and writer. (diff) | |
| download | gpgme-9f330be8210d2498fe93d4166b6f6c02fca76475.tar.gz gpgme-9f330be8210d2498fe93d4166b6f6c02fca76475.zip | |
Fix hang in socket closing.
* src/w32-io.c (destroy_reader): Call shutdown.
(reader): Do not print an error in the shutdown case.
| -rw-r--r-- | src/w32-io.c | 36 | 
1 files changed, 36 insertions, 0 deletions
| diff --git a/src/w32-io.c b/src/w32-io.c index 164205e8..776e3792 100644 --- a/src/w32-io.c +++ b/src/w32-io.c @@ -316,6 +316,21 @@ reader (void *arg)                  }                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;                    TRACE_LOG1 ("recv error: ec=%d", ctx->error_code);                  } @@ -357,6 +372,7 @@ reader (void *arg)  	  UNLOCK (ctx->mutex);  	  break;          } +        TRACE_LOG1 ("got %u bytes", nread);        ctx->writepos = (ctx->writepos + nread) % READBUF_SIZE; @@ -495,6 +511,26 @@ destroy_reader (struct reader_context_s *ctx)      }  #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,  	  "waiting for termination of thread %p", ctx->thread_hd);    WaitForSingleObject (ctx->stopped, INFINITE); | 
