[Pkg-gnupg-commit] [libassuan] 318/437: 2010-06-09 Marcus Brinkmann <marcus at g10code.de>

Eric Dorland eric at moszumanska.debian.org
Fri May 22 05:33:58 UTC 2015


This is an automated email from the git hooks/post-receive script.

eric pushed a commit to branch master
in repository libassuan.

commit 64360f7f70d783da90945f68674f23614683d39a
Author: Marcus Brinkmann <mb at g10code.com>
Date:   Wed Jun 9 13:12:31 2010 +0000

    2010-06-09  Marcus Brinkmann  <marcus at g10code.de>
    
    	* gpgcedev.c (GPGCEDEV_IOCTL_UNBLOCK): New ioctl.
    	(PIPE_FLAG_UNBLOCK_READER, PIPE_FLAG_UNBLOCK_WRITER): New flags.
    	(GPG_Read): Check if PIPE_FLAG_UNBLOCK_READER is set and return
    	ERROR_BUSY in that case.
    	(GPG_Write): Likewise for PIPE_FLAG_UNBLOCK_WRITER.
    	(unblock_call): New function.
    	(GPG_IOControl): Implement GPGCEDEV_IOCTL_UNBLOCK.
---
 src/ChangeLog  | 10 +++++++++
 src/gpgcedev.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 81 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index fd2a293..dc20d24 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,13 @@
+2010-06-09  Marcus Brinkmann  <marcus at g10code.de>
+
+	* gpgcedev.c (GPGCEDEV_IOCTL_UNBLOCK): New ioctl.
+	(PIPE_FLAG_UNBLOCK_READER, PIPE_FLAG_UNBLOCK_WRITER): New flags.
+	(GPG_Read): Check if PIPE_FLAG_UNBLOCK_READER is set and return
+	ERROR_BUSY in that case.
+	(GPG_Write): Likewise for PIPE_FLAG_UNBLOCK_WRITER.
+	(unblock_call): New function.
+	(GPG_IOControl): Implement GPGCEDEV_IOCTL_UNBLOCK.
+
 2010-06-07  Marcus Brinkmann  <marcus at g10code.de>
 
 	* gpgcedev.c: This rewrite does away with troublesome race
diff --git a/src/gpgcedev.c b/src/gpgcedev.c
index 357c488..c0feda9 100644
--- a/src/gpgcedev.c
+++ b/src/gpgcedev.c
@@ -54,6 +54,17 @@
 #define GPGCEDEV_IOCTL_MAKE_PIPE \
   CTL_CODE (FILE_DEVICE_STREAMS, 2049, METHOD_BUFFERED, FILE_ANY_ACCESS)
 
+/* The IOCTL used to unblock a blocking thread.
+
+   The caller sends this IOCTL to the read or the write handle.  No
+   parameter is required.  The effect is that a reader or writer
+   blocked on the same handle is unblocked (and will return
+   ERROR_BUSY).  Note that the operation can be repeated, if so
+   desired.  The state of the pipe itself will not be affected in any
+   way.  */
+#define GPGCEDEV_IOCTL_UNBLOCK \
+  CTL_CODE (FILE_DEVICE_STREAMS, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
 struct pipeimpl_s
 {
   CRITICAL_SECTION critsect;  /* Lock for all members.  */
@@ -66,6 +77,8 @@ struct pipeimpl_s
 
 #define PIPE_FLAG_NO_READER 1
 #define PIPE_FLAG_NO_WRITER 2
+#define PIPE_FLAG_UNBLOCK_READER 4
+#define PIPE_FLAG_UNBLOCK_WRITER 8
   int flags;
 
   HANDLE space_available; /* Set if space is available.  */
@@ -488,6 +501,16 @@ GPG_Read (DWORD opnctx_arg, void *buffer, DWORD count)
 	  goto leave;
 	}
 
+      /* Check for request to unblock once.  */
+      if (pimpl->flags & PIPE_FLAG_UNBLOCK_READER)
+	{
+	  log_debug ("GPG_Read (ctx=0x%p): success: EBUSY (due to unblock request)\n", (void*)ctx);
+	  pimpl->flags &= ~PIPE_FLAG_UNBLOCK_READER;
+	  SetLastError (ERROR_BUSY);
+	  result = -1;
+	  goto leave;
+	}
+
       LeaveCriticalSection (&pimpl->critsect);
       log_debug ("GPG_Read (ctx=0x%p): waiting: data_available\n", (void*)ctx);
       WaitForSingleObject (data_available, INFINITE);
@@ -561,6 +584,16 @@ GPG_Write (DWORD opnctx_arg, const void *buffer, DWORD count)
       goto leave;
     }
 
+  /* Check for request to unblock once.  */
+  if (pimpl->flags & PIPE_FLAG_UNBLOCK_WRITER)
+    {
+      log_debug ("GPG_Write (ctx=0x%p): success: EBUSY (due to unblock request)\n", (void*)ctx);
+      pimpl->flags &= ~PIPE_FLAG_UNBLOCK_WRITER;
+      SetLastError (ERROR_BUSY);
+      result = -1;
+      goto leave;
+    }
+
   /* Write to our buffer.  */
   if (pimpl->buffer_len == pimpl->buffer_size)
     {
@@ -695,6 +728,30 @@ make_pipe (opnctx_t ctx, LONG rvid)
 }
 
 
+/* opnctx_table_s is locked on entering and on exit.  */
+static BOOL
+unblock_call (opnctx_t ctx)
+{
+  /* If there is no pipe object, no thread can be blocked.  */
+  if (!ctx->pipeimpl)
+    return TRUE;
+
+  EnterCriticalSection (&ctx->pipeimpl->critsect);
+  if (ctx->access_code & GENERIC_READ)
+    {
+      ctx->pipeimpl->flags |= PIPE_FLAG_UNBLOCK_READER;
+      SetEvent (ctx->pipeimpl->data_available);
+    }
+  else if (ctx->access_code & GENERIC_WRITE)
+    {
+      ctx->pipeimpl->flags |= PIPE_FLAG_UNBLOCK_WRITER;
+      SetEvent (ctx->pipeimpl->space_available);
+    }
+  LeaveCriticalSection (&ctx->pipeimpl->critsect);
+
+  return TRUE;
+}
+
 BOOL
 GPG_IOControl (DWORD opnctx_arg, DWORD code, void *inbuf, DWORD inbuflen,
                void *outbuf, DWORD outbuflen, DWORD *actualoutlen)
@@ -754,6 +811,20 @@ GPG_IOControl (DWORD opnctx_arg, DWORD code, void *inbuf, DWORD inbuflen,
         result = TRUE;
       break;
 
+    case GPGCEDEV_IOCTL_UNBLOCK:
+      log_debug ("GPG_IOControl (ctx=0x%p): code: UNBLOCK\n", (void*)opnctx);
+      if (inbuf || inbuflen || outbuf || outbuflen || actualoutlen)
+        {
+	  log_debug ("GPG_IOControl (ctx=0x%p): error: invalid parameter\n", 
+		     (void*)opnctx);
+          SetLastError (ERROR_INVALID_PARAMETER);
+          goto leave;
+        }
+      
+      if (unblock_call (opnctx))
+        result = TRUE;
+      break;
+
     case IOCTL_PSL_NOTIFY:
       log_debug ("GPG_IOControl (ctx=0x%p): code: NOTIFY\n", (void*)opnctx);
       /* Unexpected process termination.  */

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/libassuan.git



More information about the Pkg-gnupg-commit mailing list