2006-02-15 Marcus Brinkmann <marcus@g10code.de>

* w32-io.c (create_writer): Make C->have_data a manually resetted
	event.
	(writer): Move code from end of if block to beginning, so it
	is also run the first time.
	(_gpgme_io_write): Move assert check after error check.  Reset
	the is_empty event, and also do it eagerly.
	(_gpgme_io_select): Unconditionally wait for the is_empty event.
This commit is contained in:
Marcus Brinkmann 2006-02-15 13:30:08 +00:00
parent c585b7895c
commit 9829cffc3c
2 changed files with 34 additions and 22 deletions

View File

@ -1,3 +1,13 @@
2006-02-15 Marcus Brinkmann <marcus@g10code.de>
* w32-io.c (create_writer): Make C->have_data a manually resetted
event.
(writer): Move code from end of if block to beginning, so it
is also run the first time.
(_gpgme_io_write): Move assert check after error check. Reset
the is_empty event, and also do it eagerly.
(_gpgme_io_select): Unconditionally wait for the is_empty event.
2006-01-26 Werner Koch <wk@g10code.com> 2006-01-26 Werner Koch <wk@g10code.com>
* w32-util.c (_gpgme_get_conf_int): New. * w32-util.c (_gpgme_get_conf_int): New.

View File

@ -438,7 +438,13 @@ writer (void *arg)
DEBUG2 ("writer thread %p for file %p started", c->thread_hd, c->file_hd ); DEBUG2 ("writer thread %p for file %p started", c->thread_hd, c->file_hd );
for (;;) { for (;;) {
LOCK (c->mutex); LOCK (c->mutex);
if ( c->stop_me ) {
UNLOCK (c->mutex);
break;
}
if ( !c->nbytes ) { if ( !c->nbytes ) {
if (!SetEvent (c->is_empty))
DEBUG1 ("SetEvent failed: ec=%d", (int)GetLastError ());
if (!ResetEvent (c->have_data) ) if (!ResetEvent (c->have_data) )
DEBUG1 ("ResetEvent failed: ec=%d", (int)GetLastError ()); DEBUG1 ("ResetEvent failed: ec=%d", (int)GetLastError ());
UNLOCK (c->mutex); UNLOCK (c->mutex);
@ -468,14 +474,6 @@ writer (void *arg)
LOCK (c->mutex); LOCK (c->mutex);
c->nbytes -= nwritten; c->nbytes -= nwritten;
if (c->stop_me) {
UNLOCK (c->mutex);
break;
}
if ( !c->nbytes ) {
if ( !SetEvent (c->is_empty) )
DEBUG1 ("SetEvent failed: ec=%d", (int)GetLastError ());
}
UNLOCK (c->mutex); UNLOCK (c->mutex);
} }
/* indicate that we have an error */ /* indicate that we have an error */
@ -505,7 +503,7 @@ create_writer (HANDLE fd)
return NULL; return NULL;
c->file_hd = fd; c->file_hd = fd;
c->have_data = CreateEvent (&sec_attr, FALSE, FALSE, NULL); c->have_data = CreateEvent (&sec_attr, TRUE, FALSE, NULL);
c->is_empty = CreateEvent (&sec_attr, TRUE, TRUE, NULL); c->is_empty = CreateEvent (&sec_attr, TRUE, TRUE, NULL);
c->stopped = CreateEvent (&sec_attr, TRUE, FALSE, NULL); c->stopped = CreateEvent (&sec_attr, TRUE, FALSE, NULL);
if (!c->have_data || !c->is_empty || !c->stopped ) { if (!c->have_data || !c->is_empty || !c->stopped ) {
@ -637,12 +635,14 @@ _gpgme_io_write ( int fd, const void *buffer, size_t count )
LOCK (c->mutex); LOCK (c->mutex);
if ( c->nbytes ) { /* bytes are pending for send */ if ( c->nbytes ) { /* bytes are pending for send */
/* Reset the is_empty event. Better safe than sorry. */
if (!ResetEvent (c->is_empty))
DEBUG1 ("ResetEvent failed: ec=%d", (int)GetLastError ());
UNLOCK (c->mutex); UNLOCK (c->mutex);
DEBUG2 ("fd %d: waiting for empty buffer in thread %p", DEBUG2 ("fd %d: waiting for empty buffer in thread %p",
fd, c->thread_hd); fd, c->thread_hd);
WaitForSingleObject (c->is_empty, INFINITE); WaitForSingleObject (c->is_empty, INFINITE);
DEBUG2 ("fd %d: thread %p buffer is empty", fd, c->thread_hd); DEBUG2 ("fd %d: thread %p buffer is empty", fd, c->thread_hd);
assert (!c->nbytes);
LOCK (c->mutex); LOCK (c->mutex);
} }
@ -651,11 +651,20 @@ _gpgme_io_write ( int fd, const void *buffer, size_t count )
DEBUG1 ("fd %d: write error", fd ); DEBUG1 ("fd %d: write error", fd );
return -1; return -1;
} }
/* If no error occured, the number of bytes in the buffer must be
zero. */
assert (!c->nbytes);
if (count > WRITEBUF_SIZE) if (count > WRITEBUF_SIZE)
count = WRITEBUF_SIZE; count = WRITEBUF_SIZE;
memcpy (c->buffer, buffer, count); memcpy (c->buffer, buffer, count);
c->nbytes = count; c->nbytes = count;
/* We have to reset the is_empty event early, because it is also
used by the select() implementation to probe the channel. */
if (!ResetEvent (c->is_empty))
DEBUG1 ("ResetEvent failed: ec=%d", (int)GetLastError ());
if (!SetEvent (c->have_data)) if (!SetEvent (c->have_data))
DEBUG1 ("SetEvent failed: ec=%d", (int)GetLastError ()); DEBUG1 ("SetEvent failed: ec=%d", (int)GetLastError ());
UNLOCK (c->mutex); UNLOCK (c->mutex);
@ -1018,18 +1027,11 @@ _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds, int nonblock )
DEBUG0 ("Too many objects for WFMO!" ); DEBUG0 ("Too many objects for WFMO!" );
return -1; return -1;
} }
LOCK (c->mutex); waitidx[nwait] = i;
if ( !c->nbytes ) { waitbuf[nwait++] = c->is_empty;
waitidx[nwait] = i;
waitbuf[nwait++] = c->is_empty;
DEBUG_ADD1 (dbg_help, "w%d ", fds[i].fd );
any = 1;
}
else {
DEBUG_ADD1 (dbg_help, "w%d(ignored) ", fds[i].fd );
}
UNLOCK (c->mutex);
} }
DEBUG_ADD1 (dbg_help, "w%d ", fds[i].fd );
any = 1;
} }
} }
} }