[svn] GpgOL - r242 - in trunk: . doc po src
svn author wk
cvs at cvs.gnupg.org
Wed Apr 2 18:10:00 CEST 2008
Author: wk
Date: 2008-04-02 18:09:58 +0200 (Wed, 02 Apr 2008)
New Revision: 242
Modified:
trunk/ChangeLog
trunk/NEWS
trunk/configure.ac
trunk/doc/gpgol.texi
trunk/po/de.po
trunk/po/sv.po
trunk/src/ChangeLog
trunk/src/Makefile.am
trunk/src/common.c
trunk/src/engine-assuan.c
trunk/src/engine.c
trunk/src/main.c
trunk/src/mimeparser.c
trunk/src/util.h
Log:
Preparing a release
[The diff below has been truncated]
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2008-03-31 16:29:54 UTC (rev 241)
+++ trunk/ChangeLog 2008-04-02 16:09:58 UTC (rev 242)
@@ -1,3 +1,7 @@
+2008-04-01 Werner Koch <wk at g10code.com>
+
+ * configure.ac (AC_INIT): Fix quoting.
+
2008-03-19 Werner Koch <wk at g10code.com>
* Release 0.10.9.
Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog 2008-03-31 16:29:54 UTC (rev 241)
+++ trunk/src/ChangeLog 2008-04-02 16:09:58 UTC (rev 242)
@@ -1,5 +1,23 @@
+2008-04-02 Werner Koch <wk at g10code.com>
+
+ * engine-assuan.c (destroy_command): Add arg FORCE.
+ (op_assuan_encrypt_bottom): Call destroy_command.
+
+ * mimeparser.c (struct mime_context): Use parser_error to return
+ gpg error codes.
+
+ * main.c (read_options): Allow names for debug flags.
+ * common.c (trim_spaces): New.
+
2008-03-31 Werner Koch <wk at g10code.com>
+ * engine-assuan.c (struct work_item_s): Add SWITCH_COUNTER.
+ (switch_threads, clear_switch_threads): New.
+ (worker_start_write): Use it.
+ * engine.c (struct engine_filter_s): Add SWITCH_COUNTER.
+ (switch_threads, clear_switch_threads): New.
+ (filter_gpgme_read_cb): Use it.
+
* ext-commands.h (class GpgolExtCommands): Add m_nCmdCryptoState.
* ext-commands.cpp (InstallCommands): Add a toolbar crypto state
button.
Modified: trunk/NEWS
===================================================================
--- trunk/NEWS 2008-03-31 16:29:54 UTC (rev 241)
+++ trunk/NEWS 2008-04-02 16:09:58 UTC (rev 242)
@@ -1,5 +1,13 @@
+Noteworthy changes for version 0.10.10 (2008-04-02)
+===================================================
+
+ * Visual cleanups.
+
+ * Changes to the I/O dispatcher.
+
+
Noteworthy changes for version 0.10.9 (2008-03-19)
-=================================================
+==================================================
* Decrypt opaque signed and encrypted S/MIME mails.
@@ -8,7 +16,7 @@
Noteworthy changes for version 0.10.8 (2008-03-18)
-=================================================
+==================================================
* Fixed a segv introduced with 0.10.6.
Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac 2008-03-31 16:29:54 UTC (rev 241)
+++ trunk/configure.ac 2008-04-02 16:09:58 UTC (rev 242)
@@ -16,12 +16,13 @@
# Remember to change the version number immediately *after* a release.
# Set my_issvn to "yes" for non-released code. Remember to run an
# "svn up" and "autogen.sh" right before creating a distribution.
-m4_define([my_version], [0.10.9])
+m4_define([my_version], [0.10.10])
m4_define([my_issvn], [no])
m4_define([svn_revision], m4_esyscmd([echo -n $( (svn info 2>/dev/null \
|| echo 'Revision: 0')|sed -n '/^Revision:/ {s/[^0-9]//gp;q;}')]))
-AC_INIT([gpgol], my_version[]m4_if(my_issvn,[yes],[-svn[]svn_revision]),
+AC_INIT([gpgol],
+ [my_version[]m4_if(my_issvn,[yes],[-svn[]svn_revision])],
[bug-gpgol at g10code.com])
NEED_GPG_ERROR_VERSION=1.4
Modified: trunk/doc/gpgol.texi
===================================================================
--- trunk/doc/gpgol.texi 2008-03-31 16:29:54 UTC (rev 241)
+++ trunk/doc/gpgol.texi 2008-04-02 16:09:58 UTC (rev 242)
@@ -661,24 +661,26 @@
make the log file output more verbose; these are actually bit flags
according to the following table (which may change with any release):
@table @code
- at item 2 (0x0002)
+ at item 2 (0x0002) (ioworker)
Tell what the Assuan I/O scheduler is doing.
- at item 4 (0x0004)
+ at item 4 (0x0004) (ioworker-extra)
Even more verbose Assuan I/O scheduler reporting.
- at item 8 (0x0008)
+ at item 8 (0x0008) (filter)
Tell what the filter I/O system is doing.
- at item 16 (0x0010)
+ at item 16 (0x0010) (filter-extra)
Tell how the filter I/O locks the resources.
- at item 32 (0x0020)
+ at item 32 (0x0020) (memory)
Tell about resource allocation.
- at item 64 (0x0040)
+ at item 64 (0x0040) (commands)
Tell about command events.
- at item 128 (0x0080)
+ at item 128 (0x0080) (mime-parser)
Tell what the MIME parser is doing
- at item 256 (0x0100)
+ at item 256 (0x0100) (mime-data)
Print data lines while parsing MIME.
@end table
-You may use the regular C-syntax for entering the value.
+You may use the regular C-syntax for entering the value. As an
+alternative you may use the names ofthe flags, separated by space or
+comma.
@itemx HKCU\Software\GNU\GpgOL:logFile
Modified: trunk/po/de.po [not shown]
Modified: trunk/po/sv.po [not shown]
Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am 2008-03-31 16:29:54 UTC (rev 241)
+++ trunk/src/Makefile.am 2008-04-02 16:09:58 UTC (rev 242)
@@ -74,13 +74,13 @@
$(DLLTOOL) --output-lib $@ --def $<
libgpg-error.a:
- ln -s $(shell $(GPG_ERROR_CONFIG) --prefix)/lib/libgpg-error.a
+ ln -s $$($(GPG_ERROR_CONFIG) --prefix)/lib/libgpg-error.a .
libgpgme.a:
- ln -s $(shell $(GPGME_CONFIG) --prefix)/lib/libgpgme.a
+ ln -s $$($(GPGME_CONFIG) --prefix)/lib/libgpgme.a .
libassuan.a:
- ln -s $(shell $(LIBASSUAN_CONFIG) --prefix)/lib/libassuan.a
+ ln -s $$($(LIBASSUAN_CONFIG) --prefix)/lib/libassuan.a .
clean-local:
rm -f libmapi32.a libgpg-error.a libgpgme.a libassuan.a
Modified: trunk/src/common.c
===================================================================
--- trunk/src/common.c 2008-03-31 16:29:54 UTC (rev 241)
+++ trunk/src/common.c 2008-04-02 16:09:58 UTC (rev 242)
@@ -413,6 +413,36 @@
}
+/* Strip off leading and trailing white spaces from STRING. Returns
+ STRING. */
+char *
+trim_spaces (char *arg_string)
+{
+ char *string = arg_string;
+ char *p, *mark;
+
+ /* Find first non space character. */
+ for (p = string; *p && isascii (*p) && isspace (*p) ; p++ )
+ ;
+ /* Move characters. */
+ for (mark = NULL; (*string = *p); string++, p++ )
+ {
+ if (isascii (*p) && isspace (*p))
+ {
+ if (!mark)
+ mark = string;
+ }
+ else
+ mark = NULL ;
+ }
+ if (mark)
+ *mark = 0;
+
+ return arg_string;
+}
+
+
+
/* Helper for read_w32_registry_string(). */
static HKEY
get_root_key(const char *root)
Modified: trunk/src/engine-assuan.c
===================================================================
--- trunk/src/engine-assuan.c 2008-03-31 16:29:54 UTC (rev 241)
+++ trunk/src/engine-assuan.c 2008-04-02 16:09:58 UTC (rev 242)
@@ -111,6 +111,8 @@
queue. */
OVERLAPPED ov; /* The overlapped info structure. */
char buffer[1024]; /* The buffer used by ReadFile or WriteFile. */
+
+ ULONG switch_counter; /* Used by switch_threads. */
};
@@ -636,6 +638,39 @@
#endif /* not used. */
+/* This is a wraper around SwitchToThread, a syscall we unfortunately
+ need due to the lack of an sophisticated event system. The wrapper
+ calls SwitchToThread but after a couple of immediate folliwing
+ switches, it introduces a short delays. */
+static void
+switch_threads (work_item_t item)
+{
+ ULONG count;
+
+ count = InterlockedExchangeAdd (&item->switch_counter, 1);
+ if (count > 5)
+ {
+ /* Tried too often without success. Use Sleep until
+ clear_switch_threads has been called. */
+ InterlockedExchange (&item->switch_counter, 5);
+ SleepEx (60, TRUE);
+ }
+ else if (!SwitchToThread ())
+ {
+ /* No runable other thread: Fall asleep. */
+ SleepEx (8, TRUE);
+ }
+}
+
+/* Call this fucntion if some action has been done. */
+static void
+clear_switch_threads (work_item_t item)
+{
+ InterlockedExchange (&item->switch_counter, 0);
+}
+
+
+
/* Helper for async_worker_thread. Returns true if the item's handle
needs to be put on the wait list. This is called with the worker
@@ -763,13 +798,16 @@
/* Read from the callback and the write to the handle. The gpgme
callback is expected to never block. */
nread = gpgme_data_read (item->data, item->buffer, sizeof item->buffer);
+ if (nread < 0 && errno == EAGAIN)
+ switch_threads (item);
+ else
+ clear_switch_threads (item);
if (nread < 0)
{
if (errno == EAGAIN)
{
/* log_debug ("%s:%s: [%s:%p] ignoring EAGAIN from callback", */
/* SRCNAME, __func__, item->name, item->hd); */
- SwitchToThread ();
retval = 1;
}
else
@@ -955,7 +993,21 @@
/* INFINITE, QS_ALLEVENTS); */
if (n == WAIT_FAILED)
{
+ int i;
+ DWORD hdinfo;
+
log_error_w32 (-1, "%s:%s: WFMO failed", SRCNAME, __func__);
+ for (i=0; i < hdarraylen; i++)
+ {
+ hdinfo = 0;
+ if (!GetHandleInformation (hdarray[i], &hdinfo))
+ log_debug_w32 (-1, "%s:%s: WFMO GetHandleInfo(%p) failed",
+ SRCNAME, __func__, hdarray[i]);
+ else
+ log_debug ("%s:%s: WFMO GetHandleInfo(%p)=0x%lu",
+ SRCNAME, __func__, hdarray[i],
+ (unsigned long)hdinfo);
+ }
Sleep (1000);
}
else if (n >= 0 && n < hdarraylen)
@@ -1060,33 +1112,60 @@
{
if (item->cld)
{
+ work_item_t itm2;
+
if (!item->cld->final_err && item->got_error)
item->cld->final_err = gpg_error (GPG_ERR_EIO);
- if (!item->cld->final_err)
+ /* Check whether there are other work items in this
+ group we need to wait for before invoking the
+ closure. */
+ for (itm2=work_queue; itm2; itm2 = itm2->next)
+ if (itm2->used && itm2 != item
+ && itm2->cmdid == item->cmdid
+ && itm2->wait_on_success
+ && !(itm2->got_ready || itm2->got_error))
+ break;
+ if (itm2)
{
- /* Check whether there are other work items in
- this group we need to wait for before
- invoking the closure. */
- work_item_t itm2;
-
- for (itm2=work_queue; itm2; itm2 = itm2->next)
- if (itm2->used && itm2 != item
- && itm2->cmdid == item->cmdid
- && itm2->wait_on_success
- && !(itm2->got_ready || itm2->got_error))
- break;
- if (itm2)
+ if (debug_ioworker)
+ log_debug ("%s:%s: [%s:%p] delaying closure "
+ "due to [%s:%p]", SRCNAME, __func__,
+ item->name, item->hd,
+ itm2->name, itm2->hd);
+ item->delayed_ready = 1;
+ if (item->cld->final_err)
{
- if (debug_ioworker)
- log_debug ("%s:%s: [%s:%p] delaying closure "
- "due to [%s/%p]", SRCNAME, __func__,
- item->name, item->hd,
- itm2->name, itm2->hd);
- item->delayed_ready = 1;
- break;
+ /* If we received an error we better do not
+ assume that the server has properly
+ closed all I/O channels. Send a cancel
+ to the work item we are waiting for. */
+ if (!itm2->aborting)
+ {
+ if (debug_ioworker)
+ log_debug ("%s:%s: [%s:%p] calling CancelIO",
+ SRCNAME, __func__,
+ itm2->name, itm2->hd);
+ itm2->aborting = 1;
+ if (!CancelIo (itm2->hd))
+ log_error_w32 (-1, "%s:%s: [%s:%p] "
+ "CancelIo failed",
+ SRCNAME,__func__,
+ itm2->name, itm2->hd);
+ }
+ else
+ {
+ if (debug_ioworker)
+ log_debug ("%s:%s: [%s:%p] clearing "
+ "wait on success flag",
+ SRCNAME, __func__,
+ itm2->name, itm2->hd);
+ itm2->wait_on_success = 0;
+ }
}
+ break;
}
+
item->delayed_ready = 0;
if (debug_ioworker)
log_debug ("%s:%s: [%s:%p] invoking closure",
@@ -1189,18 +1268,19 @@
/* Remove all items from the work queue belonging to the command with
the id CMDID. */
static void
-destroy_command (ULONG cmdid)
+destroy_command (ULONG cmdid, int force)
{
work_item_t item;
EnterCriticalSection (&work_queue_lock);
for (item = work_queue; item; item = item->next)
- if (item->used && item->cmdid == cmdid && !item->wait_on_success)
+ if (item->used && item->cmdid == cmdid
+ && (!item->wait_on_success || force))
{
if (debug_ioworker)
log_debug ("%s:%s: [%s:%p] cmdid=%lu registered for destroy",
SRCNAME, __func__, item->name, item->hd, item->cmdid);
- /* First send an I/O cancel in case the the last
+ /* First send an I/O cancel in case the last
GetOverlappedResult returned only a partial result. This
works because we are always running within the
async_worker_thread. */
@@ -1315,7 +1395,7 @@
break;
case 1: /* Ready. */
cld->status_ready = 1;
- destroy_command (cld->cmdid);
+ destroy_command (cld->cmdid, 0);
break;
default:
log_error ("%s:%s: invalid line from server", SRCNAME, __func__);
@@ -1432,7 +1512,7 @@
correct relationship between a popups and the active window. If
this function returns success, the data objects may only be
destroyed after an engine_wait or engine_cancel. On success the
- fucntion returns a pojunter to the encryption state and thus
+ function returns a poiunter to the encryption state and thus
requires that op_assuan_encrypt_bottom will be run later. */
int
op_assuan_encrypt (protocol_t protocol,
@@ -1579,11 +1659,15 @@
if (err)
{
- /* Fixme: Cancel stuff in the work_queue. */
+ xfree (encstate->cld);
+ encstate->cld = NULL;
+ engine_private_set_cancel (encstate->filter, NULL);
close_pipe (encstate->inpipe);
close_pipe (encstate->outpipe);
- xfree (encstate->cld);
+ if (cancel)
+ destroy_command (encstate->cmdid, 1);
assuan_disconnect (encstate->ctx);
+ encstate->ctx = NULL;
}
else
engine_private_set_cancel (encstate->filter, encstate->ctx);
Modified: trunk/src/engine.c
===================================================================
--- trunk/src/engine.c 2008-03-31 16:29:54 UTC (rev 241)
+++ trunk/src/engine.c 2008-04-02 16:09:58 UTC (rev 242)
@@ -105,6 +105,9 @@
/* A pointer used convey information from engine_encrypt_prepare to
engine_encrypt_start. */
struct engine_assuan_encstate_s *encstate;
+
+ /* Counter used to optimize voluntary thread switching. */
+ ULONG switch_counter;
};
@@ -198,8 +201,36 @@
}
+/* This is a wraper around SwitchToThread, a syscall we unfortunately
+ need due to the lack of an sophisticated event system. The wrapper
+ calls SwitchToThread but after a couple of immediate folliwing
+ switches, it introduces a short delays. */
+static void
+switch_threads (engine_filter_t filter)
+{
+ ULONG count;
+ count = InterlockedExchangeAdd (&filter->switch_counter, 1);
+ if (count > 5)
+ {
+ InterlockedExchange (&filter->switch_counter, 5);
+ SleepEx (50, TRUE);
+ }
+ else if (!SwitchToThread ())
+ {
+ /* No runable other thread: Fall asleep. */
+ SleepEx (5, TRUE);
+ }
+}
+/* Call this fucntion if some action has been done. */
+static void
+clear_switch_threads (engine_filter_t filter)
+{
+ InterlockedExchange (&filter->switch_counter, 0);
+}
+
+
/* This read callback is used by GPGME to read data from a filter
object. The function should return the number of bytes read, 0 on
EOF, and -1 on error. If an error occurs, ERRNO should be set to
@@ -234,9 +265,11 @@
errno = EAGAIN;
if (debug_filter_extra)
log_debug ("%s:%s: leave; result=EAGAIN\n", SRCNAME, __func__);
- SwitchToThread ();
+ switch_threads (filter);
return -1;
}
+ else
+ clear_switch_threads (filter);
if (debug_filter)
log_debug ("%s:%s: waiting for in.condvar\n", SRCNAME, __func__);
WaitForSingleObject (filter->in.condvar, 500);
@@ -425,8 +458,11 @@
SRCNAME, __func__, indata, (int)indatalen, filter->outfnc);
for (;;)
{
+ int any;
+
/* If there is something to write out, do this now to make space
for more data. */
+ any = 0;
take_out_lock (filter, __func__);
while (filter->out.length)
{
@@ -447,13 +483,19 @@
memmove (filter->out.buffer, filter->out.buffer + nbytes,
filter->out.length - nbytes);
filter->out.length -= nbytes;
+ any = 1;
}
if (!PulseEvent (filter->out.condvar))
log_error_w32 (-1, "%s:%s: PulseEvent(out) failed", SRCNAME, __func__);
release_out_lock (filter, __func__);
-
+
+ if (any)
+ clear_switch_threads (filter);
+ else
+ switch_threads (filter);
+
+ any = 0;
take_in_lock (filter, __func__);
-
if (!indata && !indatalen)
{
filter->in.got_eof = 1;
@@ -480,17 +522,23 @@
memcpy (filter->in.buffer, indata, filter->in.length);
indata += filter->in.length;
indatalen -= filter->in.length;
+ any = 1;
}
+ /* Terminate the loop if the filter queue is empty OR the filter
+ is ready and there is nothing left for output. */
if (!filter->in.length || (filter->in.ready && !filter->out.length))
{
release_in_lock (filter, __func__);
More information about the Gnupg-commits
mailing list