From 2c0fb06051291d82642ca32811026d10c3350ba6 Mon Sep 17 00:00:00 2001 From: Colin Leroy Date: Mon, 9 Aug 2004 14:07:40 +0000 Subject: [PATCH] Make SSL_connect nonblocking, using a thread --- ChangeLog.claws | 8 ++++++ PATCHSETS | 1 + configure.ac | 5 +++- src/common/ssl.c | 61 ++++++++++++++++++++++++++++++++++++++++++- src/common/sylpheed.c | 12 +++++++++ src/common/sylpheed.h | 2 ++ src/main.c | 8 ++++++ 7 files changed, 95 insertions(+), 2 deletions(-) diff --git a/ChangeLog.claws b/ChangeLog.claws index d4e0dc4f9..e30d3444a 100644 --- a/ChangeLog.claws +++ b/ChangeLog.claws @@ -1,3 +1,11 @@ +2004-08-09 [colin] 0.9.12cvs55 + + * src/main.c + * src/common/ssl.c + * src/common/sylpheed.c + * src/common/sylpheed.h + Make SSL_connect nonblocking, using a thread + 2004-08-09 [paul] 0.9.12cvs54 * po/POTFILES.in diff --git a/PATCHSETS b/PATCHSETS index c512a9aee..11dd82d87 100644 --- a/PATCHSETS +++ b/PATCHSETS @@ -36,3 +36,4 @@ ( cvs diff -u -r 1.1110 -r 1.1111 configure.ac; cvs diff -u -r 1.183 -r 1.184 src/Makefile.am; cvs diff -u -r 1.137 -r 1.138 src/main.c; cvs diff -u -r -1.12 -r -1.13 src/pgpmime.c; cvs diff -u -r -1.1 -r -1.2 src/pgpmime.h; cvs diff -u -r -1.15 -r -1.16 src/sgpgme.c; cvs diff -u -r -1.5 -r -1.6 src/sgpgme.h; cvs diff -u -r 1.8 -r 1.9 src/plugins/Makefile.am; cvs diff -u -r 0 -r 1 src/plugins/pgpmime/.cvsignore; cvs diff -u -r 0 -r 1 src/plugins/pgpmime/Makefile.am; cvs diff -u -r 0 -r 1 src/plugins/pgpmime/pgpmime.c; cvs diff -u -r 0 -r 1 src/plugins/pgpmime/pgpmime.h; cvs diff -u -r 0 -r 1 src/plugins/pgpmime/plugin.c; cvs diff -u -r 0 -r 1 src/plugins/pgpmime/sgpgme.c; cvs diff -u -r 0 -r 1 src/plugins/pgpmime/sgpgme.h; ) > 0.9.12cvs52.patchset ( cvs diff -u -r 1.5 -r 1.6 src/folderutils.c; ) > 0.9.12cvs53.patchset ( cvs diff -u -r 1.71 -r 1.72 po/POTFILES.in; cvs diff -u -r 1.138 -r 1.139 src/main.c ) > 0.9.12cvs54.patchset +( cvs diff -u -r 1.139 -r 1.140 src/main.c; cvs diff -u -r 1.13 -r 1.14 src/common/ssl.c; cvs diff -u -r 1.7 -r 1.8 src/common/sylpheed.c; cvs diff -u -r 1.5 -r 1.6 src/common/sylpheed.h; ) > 0.9.12cvs55.patchset diff --git a/configure.ac b/configure.ac index fe36823e7..7b8f78955 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ MINOR_VERSION=9 MICRO_VERSION=12 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=54 +EXTRA_VERSION=55 EXTRA_RELEASE= if test \( $EXTRA_VERSION -eq 0 \) -o \( "x$EXTRA_RELEASE" != "x" \); then @@ -555,6 +555,9 @@ fi AC_SUBST(CLAMAV_LIBS) AM_CONDITIONAL(BUILD_CLAMAV_PLUGIN, test x"$ac_cv_enable_clamav_plugin" = xyes) +AC_CHECK_LIB(pthread, pthread_create, + [ OPENSSL_LIBS="$OPENSSL_LIBS -lpthread" AC_DEFINE(USE_PTHREAD, 1, Define if you have lpthread) ]) + dnl **************************** dnl ** Final configure output ** dnl **************************** diff --git a/src/common/ssl.c b/src/common/ssl.c index 27f9fdf39..f063ec818 100644 --- a/src/common/ssl.c +++ b/src/common/ssl.c @@ -27,11 +27,24 @@ #include +#include "sylpheed.h" #include "intl.h" #include "utils.h" #include "ssl.h" #include "ssl_certificate.h" +#ifdef USE_PTHREAD +#include +#endif + +#ifdef USE_PTHREAD +typedef struct _thread_data { + SSL *ssl; + gboolean done; +} thread_data; +#endif + + static SSL_CTX *ssl_ctx; void ssl_init(void) @@ -62,6 +75,52 @@ void ssl_done(void) SSL_CTX_free(ssl_ctx); } +#ifdef USE_PTHREAD +void *SSL_connect_thread(void *data) +{ + thread_data *td = (thread_data *)data; + int result = SSL_connect(td->ssl); + td->done = TRUE; /* let the caller thread join() */ + return GINT_TO_POINTER(result); +} +#endif + +gint SSL_connect_nb(SSL *ssl) +{ +#ifdef USE_PTHREAD + thread_data *td = g_new0(thread_data, 1); + pthread_t pt; + void *res = NULL; + + td->ssl = ssl; + td->done = FALSE; + + /* try to create a thread to initialize the SSL connection, + * fallback to blocking method in case of problem + */ + if (pthread_create(&pt, PTHREAD_CREATE_JOINABLE, + SSL_connect_thread, td) != 0) + return SSL_connect(ssl); + + debug_print("waiting for SSL_connect thread...\n"); + while(!td->done) { + /* don't let the interface freeze while waiting */ + sylpheed_do_idle(); + } + + /* get the thread's return value and clean its resources */ + pthread_join(pt, &res); + g_free(td); + + debug_print("SSL_connect thread returned %d\n", + GPOINTER_TO_INT(res)); + + return GPOINTER_TO_INT(res); +#else + return SSL_connect(ssl); +#endif +} + gboolean ssl_init_socket(SockInfo *sockinfo) { return ssl_init_socket_with_method(sockinfo, SSL_METHOD_SSLv23); @@ -92,7 +151,7 @@ gboolean ssl_init_socket_with_method(SockInfo *sockinfo, SSLMethod method) } SSL_set_fd(ssl, sockinfo->sock); - if (SSL_connect(ssl) == -1) { + if (SSL_connect_nb(ssl) == -1) { g_warning(_("SSL connect failed (%s)\n"), ERR_error_string(ERR_get_error(), NULL)); SSL_free(ssl); diff --git a/src/common/sylpheed.c b/src/common/sylpheed.c index e00231e26..4e2ee2e93 100644 --- a/src/common/sylpheed.c +++ b/src/common/sylpheed.c @@ -37,6 +37,7 @@ static gboolean sylpheed_initialized = FALSE; static gchar *startup_dir; +static void (*sylpheed_idle_function)(void) = NULL; /** * Parse program parameters and remove all parameters @@ -134,3 +135,14 @@ guint sylpheed_get_version(void) { return VERSION_NUMERIC; } + +void sylpheed_register_idle_function (void (*idle_func)(void)) +{ + sylpheed_idle_function = idle_func; +} + +void sylpheed_do_idle(void) +{ + if (sylpheed_idle_function != NULL) + sylpheed_idle_function(); +} diff --git a/src/common/sylpheed.h b/src/common/sylpheed.h index f7a9b1bfd..8233def87 100644 --- a/src/common/sylpheed.h +++ b/src/common/sylpheed.h @@ -26,5 +26,7 @@ gboolean sylpheed_init (int *argc, char ***argv); void sylpheed_done (void); const gchar *sylpheed_get_startup_dir (void); guint sylpheed_get_version (void); +void sylpheed_register_idle_function (void (*idle_func)(void)); +void sylpheed_do_idle (void); #endif /* SYLPHEED_H */ diff --git a/src/main.c b/src/main.c index 7a7882100..c3538405a 100644 --- a/src/main.c +++ b/src/main.c @@ -165,6 +165,12 @@ _("File `%s' already exists.\n" static MainWindow *static_mainwindow; +void sylpheed_gtk_idle(void) +{ + while(gtk_events_pending()) + gtk_main_iteration(); +} + int main(int argc, char *argv[]) { gchar *userrc; @@ -351,6 +357,8 @@ int main(int argc, char *argv[]) cmd.status_full_folders = NULL; } + sylpheed_register_idle_function(sylpheed_gtk_idle); + prefs_toolbar_init(); plugin_load_all("GTK"); -- 2.25.1