GPA does now work with the glib based i/o backend.

This commit is contained in:
Werner Koch 2005-11-18 16:52:38 +00:00
parent 3418d23ec5
commit 6b24b361ad
7 changed files with 121 additions and 50 deletions

View File

@ -1,8 +1,16 @@
2005-11-18 Werner Koch <wk@g10code.com>
* configure.ac (BUILD_REVISION): New.
2005-11-17 Marcus Brinkmann <marcus@g10code.de> 2005-11-17 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Add support for --enable-w32-glib (disabled by * configure.ac: Add support for --enable-w32-glib (disabled by
default). Invoke AM_PATH_GLIB_2_0. default). Invoke AM_PATH_GLIB_2_0.
2005-11-16 Werner Koch <wk@g10code.com>
* configure.ac (CFLAGS) [W32]: Make sure that -mms-bitfields are used.
2005-11-15 Werner Koch <wk@g10code.com> 2005-11-15 Werner Koch <wk@g10code.com>
* configure.ac: Create BUILD_FILEVERSION from SVN Revision. * configure.ac: Create BUILD_FILEVERSION from SVN Revision.

View File

@ -76,7 +76,8 @@ if test "$1" = "--build-w32"; then
./configure --enable-maintainer-mode --prefix=${w32root} \ ./configure --enable-maintainer-mode --prefix=${w32root} \
--host=i586-mingw32msvc --build=${build} \ --host=i586-mingw32msvc --build=${build} \
--with-gpg-error-prefix=${w32root} --without-gpgsm \ --with-gpg-error-prefix=${w32root} --without-gpgsm \
--enable-shared --enable-static --enable-shared --enable-static --enable-w32-glib \
PKG_CONFIG_LIBDIR="$w32root/lib/pkgconfig"
exit $? exit $?
fi fi

View File

@ -170,6 +170,9 @@ AC_TYPE_OFF_T
# Checks for compiler features. # Checks for compiler features.
if test "$GCC" = yes; then if test "$GCC" = yes; then
CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes" CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes"
if test "$have_w32_system" = yes; then
CFLAGS="$CFLAGS -mms-bitfields"
fi
fi fi
@ -449,15 +452,18 @@ AM_CONDITIONAL(BUILD_COMPLUS, test "$component_system" = "COM+")
GNUPG_FIX_HDR_VERSION(gpgme/gpgme.h, GPGME_VERSION) GNUPG_FIX_HDR_VERSION(gpgme/gpgme.h, GPGME_VERSION)
# Generate values for the DLL version info # Generate values for the DLL version info
changequote(,)dnl
BUILD_REVISION="`echo '$Revision$' | sed 's/[^0-9]//g'`"
changequote([,])dnl
test -z "$BUILD_REVISION" && BUILD_REVISION="0"
if test "$have_w32_system" = yes; then if test "$have_w32_system" = yes; then
BUILD_TIMESTAMP=`date --iso-8601=minutes` BUILD_TIMESTAMP=`date --iso-8601=minutes`
changequote(,)dnl changequote(,)dnl
BUILD_FILEVERSION=`echo "$VERSION" | sed 's/\([0-9.]*\).*/\1./;s/\./,/g'` BUILD_FILEVERSION=`echo "$VERSION" | sed 's/\([0-9.]*\).*/\1./;s/\./,/g'`
tmp="`echo '$Revision$' | sed 's/[^0-9]//g'`"
changequote([,])dnl changequote([,])dnl
test -z "$tmp" && tmp="0" BUILD_FILEVERSION="${BUILD_FILEVERSION}${BUILD_REVISION}"
BUILD_FILEVERSION="${BUILD_FILEVERSION}$tmp"
fi fi
AC_SUBST(BUILD_REVISION)
AC_SUBST(BUILD_TIMESTAMP) AC_SUBST(BUILD_TIMESTAMP)
AC_SUBST(BUILD_FILEVERSION) AC_SUBST(BUILD_FILEVERSION)

View File

@ -4738,7 +4738,7 @@ decide when to check the file descriptors and when to invoke the
callback functions. Usually this is done in an event loop, that also callback functions. Usually this is done in an event loop, that also
checks for events in other parts of the program. If the callback checks for events in other parts of the program. If the callback
functions are only called when the file descriptors are ready, functions are only called when the file descriptors are ready,
@acronym{GPGME} will never block. This gives the user mroe control @acronym{GPGME} will never block. This gives the user more control
over the program flow, and allows to perform other tasks when over the program flow, and allows to perform other tasks when
@acronym{GPGME} would block otherwise. @acronym{GPGME} would block otherwise.
@ -4777,7 +4777,7 @@ the return value to be reserved for later use.
@deftp {Data type} {gpgme_error_t (*gpgme_register_io_cb_t) (@w{void *@var{data}}, @w{int @var{fd}}, @w{int @var{dir}}, @w{gpgme_io_cb_t @var{fnc}}, @w{void *@var{fnc_data}}, @w{void **@var{tag}})} @deftp {Data type} {gpgme_error_t (*gpgme_register_io_cb_t) (@w{void *@var{data}}, @w{int @var{fd}}, @w{int @var{dir}}, @w{gpgme_io_cb_t @var{fnc}}, @w{void *@var{fnc_data}}, @w{void **@var{tag}})}
@tindex gpgme_register_io_cb_t @tindex gpgme_register_io_cb_t
The @code{gpgme_register_io_cb_t} type is the type of functions which can The @code{gpgme_register_io_cb_t} type is the type of functions which can
be called by @acronym{GPGME} to register an I/O callback funtion be called by @acronym{GPGME} to register an I/O callback function
@var{fnc} for the file descriptor @var{fd} with the user. @var{fnc} for the file descriptor @var{fd} with the user.
@var{fnc_data} should be passed as the first argument to @var{fnc} @var{fnc_data} should be passed as the first argument to @var{fnc}
when the handler is invoked (the second argument should be @var{fd}). when the handler is invoked (the second argument should be @var{fd}).

View File

@ -1,3 +1,12 @@
2005-11-18 Werner Koch <wk@g10code.com>
* w32-glib-io.c: Include glib.h before windows to avoid a symbol
shadowing warning.
(find_channel): Better use g_io_channel_win32_new_fd instead of
the autodetection function g_io_channel_unix_new.
(_gpgme_io_select): Rewritten. It is now a fully working select
implementation.
2005-11-18 Marcus Brinkmann <marcus@g10code.de> 2005-11-18 Marcus Brinkmann <marcus@g10code.de>
* priv-io.h (_gpgme_io_fd2str): New prototype. * priv-io.h (_gpgme_io_fd2str): New prototype.
@ -12,6 +21,10 @@
but we create pseudo fds in a private namespace that designate a but we create pseudo fds in a private namespace that designate a
handle and potentially a giochannel. handle and potentially a giochannel.
2005-11-18 Werner Koch <wk@g10code.com>
* versioninfo.rc.in: Set file version to LT-version + Svn-revision.
2005-11-17 Marcus Brinkmann <marcus@g10code.de> 2005-11-17 Marcus Brinkmann <marcus@g10code.de>
* w32-glib-io.c: New file. * w32-glib-io.c: New file.

View File

@ -18,7 +18,7 @@
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION @BUILD_FILEVERSION@ FILEVERSION @LIBGPGME_LT_CURRENT@,@LIBGPGME_LT_AGE@,@LIBGPGME_LT_REVISION@,@BUILD_REVISION@
PRODUCTVERSION @BUILD_FILEVERSION@ PRODUCTVERSION @BUILD_FILEVERSION@
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
@ -37,7 +37,7 @@ BEGIN
VALUE "Comments", "Provided under the terms of the GNU Lesser General Public License.\0" VALUE "Comments", "Provided under the terms of the GNU Lesser General Public License.\0"
VALUE "CompanyName", "g10 Code GmbH\0" VALUE "CompanyName", "g10 Code GmbH\0"
VALUE "FileDescription", "GPGME - GnuPG Made Easy\0" VALUE "FileDescription", "GPGME - GnuPG Made Easy\0"
VALUE "FileVersion", "@VERSION@\0" VALUE "FileVersion", "@LIBGPGME_LT_CURRENT@.@LIBGPGME_LT_AGE@.@LIBGPGME_LT_REVISION@.@BUILD_REVISION@\0"
VALUE "InternalName", "gpgme\0" VALUE "InternalName", "gpgme\0"
VALUE "LegalCopyright", "Copyright © 2005 g10 Code GmbH\0" VALUE "LegalCopyright", "Copyright © 2005 g10 Code GmbH\0"
VALUE "LegalTrademarks", "\0" VALUE "LegalTrademarks", "\0"

View File

@ -32,6 +32,7 @@
#include <unistd.h> #include <unistd.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#include <glib.h>
#include <windows.h> #include <windows.h>
#include <io.h> #include <io.h>
@ -40,7 +41,6 @@
#include "sema.h" #include "sema.h"
#include "debug.h" #include "debug.h"
#include <glib.h>
/* This file is an ugly hack to get GPGME working with glib on Windows /* This file is an ugly hack to get GPGME working with glib on Windows
@ -81,7 +81,7 @@ find_channel (int fd, int create)
return NULL; return NULL;
if (create && !giochannel_table[fd]) if (create && !giochannel_table[fd])
giochannel_table[fd] = g_io_channel_unix_new (fd); giochannel_table[fd] = g_io_channel_win32_new_fd (fd);
return giochannel_table[fd]; return giochannel_table[fd];
} }
@ -515,72 +515,115 @@ _gpgme_io_spawn ( const char *path, char **argv,
int int
_gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock) _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
{ {
int i; int npollfds;
int res = 0; GPollFD *pollfds;
int *pollfds_map;
int i, j;
int any, n, count;
int timeout = 1000; /* Use a 1s timeout. */
void *dbg_help = NULL; void *dbg_help = NULL;
/* Use g_io_channel_get_buffer_condition. This will help with the if (nonblock)
_gpgme_io_select uses in rungpg.c and wait.c::_gpgme_run_io_cb, timeout = 0;
but not with the global or private event loop. The user still
must define io cbs for all operations. */
if (!nonblock) pollfds = calloc (nfds, sizeof *pollfds);
assert (!"Can not provide blocking select on this target."); if (!pollfds)
return -1;
pollfds_map = calloc (nfds, sizeof *pollfds_map);
if (!pollfds_map)
{
free (pollfds);
return -1;
}
npollfds = 0;
DEBUG_BEGIN (dbg_help, 3, "gpgme:select on [ "); DEBUG_BEGIN (dbg_help, 3, "gpgme:select on [ ");
any = 0;
for (i = 0; i < nfds; i++) for (i = 0; i < nfds; i++)
{ {
if (fds[i].fd == -1) if (fds[i].fd == -1)
continue; continue;
if (fds[i].frozen) if (fds[i].frozen)
DEBUG_ADD1 (dbg_help, "f%d ", fds[i].fd); DEBUG_ADD1 (dbg_help, "f%d ", fds[i].fd);
else if (fds[i].for_read) else if (fds[i].for_read )
{ {
GIOChannel *chan = find_channel (fds[i].fd, 0); GIOChannel *chan = find_channel (fds[i].fd, 0);
assert (chan); assert (chan);
g_io_channel_win32_make_pollfd (chan, G_IO_IN, pollfds + npollfds);
DEBUG2("channel %p cond %i\n", pollfds_map[npollfds] = i;
chan, DEBUG_ADD2 (dbg_help, "r%d<%d> ", fds[i].fd, pollfds[npollfds].fd);
g_io_channel_get_buffer_condition (chan)); npollfds++;
any = 1;
if (g_io_channel_get_buffer_condition (chan) & G_IO_IN)
{
fds[i].signaled = 1;
res++;
}
DEBUG_ADD1 (dbg_help, "r%d ", fds[i].fd);
} }
else if (fds[i].for_write) else if (fds[i].for_write)
{ {
GIOChannel *chan = find_channel (fds[i].fd, 0); GIOChannel *chan = find_channel (fds[i].fd, 0);
assert (chan); assert (chan);
g_io_channel_win32_make_pollfd (chan, G_IO_OUT, pollfds + npollfds);
if (g_io_channel_get_buffer_condition (chan) & G_IO_OUT) pollfds_map[npollfds] = i;
{ DEBUG_ADD2 (dbg_help, "w%d<%d> ", fds[i].fd, pollfds[npollfds].fd);
fds[i].signaled = 1; npollfds++;
res++; any = 1;
}
DEBUG_ADD1 (dbg_help, "w%d ", fds[i].fd);
} }
else fds[i].signaled = 0;
fds[i].signaled = 0;
} }
DEBUG_END (dbg_help, "]"); DEBUG_END (dbg_help, "]");
if (!any)
{
count = 0;
goto leave;
}
count = g_io_channel_win32_poll (pollfds, npollfds, timeout);
if (count < 0)
{
int saved_errno = errno;
DEBUG1 ("_gpgme_io_select failed: %s\n", strerror (errno));
errno = saved_errno;
goto leave;
}
DEBUG_BEGIN (dbg_help, 3, "select OK [ "); DEBUG_BEGIN (dbg_help, 3, "select OK [ ");
if (DEBUG_ENABLED (dbg_help)) if (DEBUG_ENABLED (dbg_help))
{ {
for (i = 0; i <= nfds; i++) for (i = 0; i < npollfds; i++)
{ {
if (fds[i].fd == -1 || fds[i].frozen || !fds[i].signaled) if ((pollfds[i].revents & G_IO_IN))
continue;
else if (fds[i].for_read)
DEBUG_ADD1 (dbg_help, "r%d ", i); DEBUG_ADD1 (dbg_help, "r%d ", i);
else if (fds[i].for_write) if ((pollfds[i].revents & G_IO_OUT))
DEBUG_ADD1 (dbg_help, "w%d ", i); DEBUG_ADD1 (dbg_help, "w%d ", i);
} }
DEBUG_END (dbg_help, "]"); DEBUG_END (dbg_help, "]");
} }
return 1; /* COUNT is used to stop the lop as soon as possible. */
for (n = count, i = 0; i < npollfds && n; i++)
{
j = pollfds_map[i];
assert (j >= 0 && j < nfds);
if (fds[j].fd == -1)
;
else if (fds[j].for_read)
{
if ((pollfds[i].revents & G_IO_IN))
{
fds[j].signaled = 1;
n--;
}
}
else if (fds[j].for_write)
{
if ((pollfds[i].revents & G_IO_OUT))
{
fds[j].signaled = 1;
n--;
}
}
}
leave:
free (pollfds);
free (pollfds_map);
return count;
} }