Make SSL_connect nonblocking, using a thread
authorColin Leroy <colin@colino.net>
Mon, 9 Aug 2004 14:07:40 +0000 (14:07 +0000)
committerColin Leroy <colin@colino.net>
Mon, 9 Aug 2004 14:07:40 +0000 (14:07 +0000)
ChangeLog.claws
PATCHSETS
configure.ac
src/common/ssl.c
src/common/sylpheed.c
src/common/sylpheed.h
src/main.c

index d4e0dc4..e30d344 100644 (file)
@@ -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
index c512a9a..11dd82d 100644 (file)
--- 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
index fe36823..7b8f789 100644 (file)
@@ -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 ****************************
index 27f9fdf..f063ec8 100644 (file)
 
 #include <glib.h>
 
+#include "sylpheed.h"
 #include "intl.h"
 #include "utils.h"
 #include "ssl.h"
 #include "ssl_certificate.h"
 
+#ifdef USE_PTHREAD
+#include <pthread.h>
+#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);
index e00231e..4e2ee2e 100644 (file)
@@ -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();
+}
index f7a9b1b..8233def 100644 (file)
@@ -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 */
index 7a78821..c353840 100644 (file)
@@ -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");