aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32-io.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/w32-io.c')
-rw-r--r--src/w32-io.c163
1 files changed, 73 insertions, 90 deletions
diff --git a/src/w32-io.c b/src/w32-io.c
index 776e3792..d896ec0e 100644
--- a/src/w32-io.c
+++ b/src/w32-io.c
@@ -162,7 +162,9 @@ struct reader_context_s
HANDLE have_data_ev;
/* This is automatically reset. */
HANDLE have_space_ev;
- HANDLE stopped;
+ /* This is manually reset but actually only triggered once. */
+ HANDLE close_ev;
+
size_t readpos, writepos;
char buffer[READBUF_SIZE];
};
@@ -194,7 +196,7 @@ struct writer_context_s
/* This is manually reset. */
HANDLE have_data;
HANDLE is_empty;
- HANDLE stopped;
+ HANDLE close_ev;
size_t nbytes;
char buffer[WRITEBUF_SIZE];
};
@@ -383,9 +385,18 @@ reader (void *arg)
}
/* Indicate that we have an error or EOF. */
if (!SetEvent (ctx->have_data_ev))
- TRACE_LOG2 ("SetEvent (0x%x) failed: ec=%d", ctx->have_data_ev,
- (int) GetLastError ());
- SetEvent (ctx->stopped);
+ TRACE_LOG2 ("SetEvent (0x%x) failed: ec=%d", ctx->have_data_ev,
+ (int) GetLastError ());
+
+ TRACE_LOG ("waiting for close");
+ WaitForSingleObject (ctx->close_ev, INFINITE);
+
+ CloseHandle (ctx->close_ev);
+ CloseHandle (ctx->have_data_ev);
+ CloseHandle (ctx->have_space_ev);
+ CloseHandle (ctx->thread_hd);
+ DESTROY_LOCK (ctx->mutex);
+ free (ctx);
return TRACE_SUC ();
}
@@ -427,16 +438,16 @@ create_reader (int fd)
if (ctx->have_data_ev)
ctx->have_space_ev = CreateEvent (&sec_attr, FALSE, TRUE, NULL);
if (ctx->have_space_ev)
- ctx->stopped = CreateEvent (&sec_attr, TRUE, FALSE, NULL);
- if (!ctx->have_data_ev || !ctx->have_space_ev || !ctx->stopped)
+ ctx->close_ev = CreateEvent (&sec_attr, TRUE, FALSE, NULL);
+ if (!ctx->have_data_ev || !ctx->have_space_ev || !ctx->close_ev)
{
TRACE_LOG1 ("CreateEvent failed: ec=%d", (int) GetLastError ());
if (ctx->have_data_ev)
CloseHandle (ctx->have_data_ev);
if (ctx->have_space_ev)
CloseHandle (ctx->have_space_ev);
- if (ctx->stopped)
- CloseHandle (ctx->stopped);
+ if (ctx->close_ev)
+ CloseHandle (ctx->close_ev);
free (ctx);
/* FIXME: Translate the error code. */
TRACE_SYSERR (EIO);
@@ -461,8 +472,8 @@ create_reader (int fd)
CloseHandle (ctx->have_data_ev);
if (ctx->have_space_ev)
CloseHandle (ctx->have_space_ev);
- if (ctx->stopped)
- CloseHandle (ctx->stopped);
+ if (ctx->close_ev)
+ CloseHandle (ctx->close_ev);
free (ctx);
TRACE_SYSERR (EIO);
return NULL;
@@ -480,6 +491,9 @@ create_reader (int fd)
}
+/* Prepare destruction of the reader thread for CTX. Returns 0 if a
+ call to this function is sufficient and destroy_reader_finish shall
+ not be called. */
static void
destroy_reader (struct reader_context_s *ctx)
{
@@ -531,24 +545,12 @@ destroy_reader (struct reader_context_s *ctx)
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);
- TRACE1 (DEBUG_SYSIO, "gpgme:destroy_reader", ctx->file_hd,
- "thread %p has terminated", ctx->thread_hd);
-
- if (ctx->stopped)
- CloseHandle (ctx->stopped);
- if (ctx->have_data_ev)
- CloseHandle (ctx->have_data_ev);
- if (ctx->have_space_ev)
- CloseHandle (ctx->have_space_ev);
- CloseHandle (ctx->thread_hd);
- DESTROY_LOCK (ctx->mutex);
- free (ctx);
+ /* After setting this event CTX is void. */
+ SetEvent (ctx->close_ev);
}
+
/* Find a reader context or create a new one. Note that the reader
context will last until a _gpgme_io_close. */
static struct reader_context_s *
@@ -585,26 +587,6 @@ find_reader (int fd, int start_it)
}
-static void
-kill_reader (int fd)
-{
- int i;
-
- LOCK (reader_table_lock);
- for (i = 0; i < reader_table_size; i++)
- {
- if (reader_table[i].used && reader_table[i].fd == fd)
- {
- destroy_reader (reader_table[i].context);
- reader_table[i].context = NULL;
- reader_table[i].used = 0;
- break;
- }
- }
- UNLOCK (reader_table_lock);
-}
-
-
int
_gpgme_io_read (int fd, void *buffer, size_t count)
{
@@ -774,7 +756,16 @@ writer (void *arg)
/* Indicate that we have an error. */
if (!SetEvent (ctx->is_empty))
TRACE_LOG1 ("SetEvent failed: ec=%d", (int) GetLastError ());
- SetEvent (ctx->stopped);
+
+ TRACE_LOG ("waiting for close");
+ WaitForSingleObject (ctx->close_ev, INFINITE);
+
+ CloseHandle (ctx->close_ev);
+ CloseHandle (ctx->have_data);
+ CloseHandle (ctx->is_empty);
+ CloseHandle (ctx->thread_hd);
+ DESTROY_LOCK (ctx->mutex);
+ free (ctx);
return TRACE_SUC ();
}
@@ -816,16 +807,16 @@ create_writer (int fd)
if (ctx->have_data)
ctx->is_empty = CreateEvent (&sec_attr, TRUE, TRUE, NULL);
if (ctx->is_empty)
- ctx->stopped = CreateEvent (&sec_attr, TRUE, FALSE, NULL);
- if (!ctx->have_data || !ctx->is_empty || !ctx->stopped)
+ ctx->close_ev = CreateEvent (&sec_attr, TRUE, FALSE, NULL);
+ if (!ctx->have_data || !ctx->is_empty || !ctx->close_ev)
{
TRACE_LOG1 ("CreateEvent failed: ec=%d", (int) GetLastError ());
if (ctx->have_data)
CloseHandle (ctx->have_data);
if (ctx->is_empty)
CloseHandle (ctx->is_empty);
- if (ctx->stopped)
- CloseHandle (ctx->stopped);
+ if (ctx->close_ev)
+ CloseHandle (ctx->close_ev);
free (ctx);
/* FIXME: Translate the error code. */
TRACE_SYSERR (EIO);
@@ -850,8 +841,8 @@ create_writer (int fd)
CloseHandle (ctx->have_data);
if (ctx->is_empty)
CloseHandle (ctx->is_empty);
- if (ctx->stopped)
- CloseHandle (ctx->stopped);
+ if (ctx->close_ev)
+ CloseHandle (ctx->close_ev);
free (ctx);
TRACE_SYSERR (EIO);
return NULL;
@@ -868,6 +859,7 @@ create_writer (int fd)
return ctx;
}
+
static void
destroy_writer (struct writer_context_s *ctx)
{
@@ -897,21 +889,8 @@ destroy_writer (struct writer_context_s *ctx)
}
#endif
- TRACE1 (DEBUG_SYSIO, "gpgme:destroy_writer", ctx->file_hd,
- "waiting for termination of thread %p", ctx->thread_hd);
- WaitForSingleObject (ctx->stopped, INFINITE);
- TRACE1 (DEBUG_SYSIO, "gpgme:destroy_writer", ctx->file_hd,
- "thread %p has terminated", ctx->thread_hd);
-
- if (ctx->stopped)
- CloseHandle (ctx->stopped);
- if (ctx->have_data)
- CloseHandle (ctx->have_data);
- if (ctx->is_empty)
- CloseHandle (ctx->is_empty);
- CloseHandle (ctx->thread_hd);
- DESTROY_LOCK (ctx->mutex);
- free (ctx);
+ /* After setting this event CTX is void. */
+ SetEvent (ctx->close_ev);
}
@@ -951,26 +930,6 @@ find_writer (int fd, int start_it)
}
-static void
-kill_writer (int fd)
-{
- int i;
-
- LOCK (writer_table_lock);
- for (i = 0; i < writer_table_size; i++)
- {
- if (writer_table[i].used && writer_table[i].fd == fd)
- {
- destroy_writer (writer_table[i].context);
- writer_table[i].context = NULL;
- writer_table[i].used = 0;
- break;
- }
- }
- UNLOCK (writer_table_lock);
-}
-
-
int
_gpgme_io_write (int fd, const void *buffer, size_t count)
{
@@ -1195,8 +1154,32 @@ _gpgme_io_close (int fd)
fd, fd_table[fd].handle, fd_table[fd].socket,
fd_table[fd].dup_from);
- kill_reader (fd);
- kill_writer (fd);
+ LOCK (reader_table_lock);
+ for (i = 0; i < reader_table_size; i++)
+ {
+ if (reader_table[i].used && reader_table[i].fd == fd)
+ {
+ destroy_reader (reader_table[i].context);
+ reader_table[i].context = NULL;
+ reader_table[i].used = 0;
+ break;
+ }
+ }
+ UNLOCK (reader_table_lock);
+
+ LOCK (writer_table_lock);
+ for (i = 0; i < writer_table_size; i++)
+ {
+ if (writer_table[i].used && writer_table[i].fd == fd)
+ {
+ destroy_writer (writer_table[i].context);
+ writer_table[i].context = NULL;
+ writer_table[i].used = 0;
+ break;
+ }
+ }
+ UNLOCK (writer_table_lock);
+
LOCK (notify_table_lock);
for (i = 0; i < DIM (notify_table); i++)
{