[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