my stab at fixing the non MT safety code in the LDAP lookup
authorAlfons Hoogervorst <alfons@proteus.demon.nl>
Sat, 13 Oct 2001 18:01:56 +0000 (18:01 +0000)
committerAlfons Hoogervorst <alfons@proteus.demon.nl>
Sat, 13 Oct 2001 18:01:56 +0000 (18:01 +0000)
ChangeLog.claws
configure.in
src/main.c
src/syldap.c
src/syldap.h

index 83da651f590b2233313593ed103d45f9877b68da..eed55006d39f6af2a03718bccb639e32f0b44b9e 100644 (file)
@@ -1,3 +1,15 @@
+2001-10-13 [alfons, christoph, melvin] 
+                       0.6.3claws15
+
+       solution #2 to solve MT-safety problems defers all GUI related calls
+       to the main thread using a gtk_idle_add() callback. discussed on
+       ircnet #sylpheed, with christoph spotting some issues with the
+       original code, and melvin allowing us to lobotomize his sylpheed.
+
+       * src/syldap.[ch], src/main.c
+               fix race problem in ldap search thread by deferring GUI 
+               stuff to main thread using gtk_idle_add()
+
 2001-10-13 [paul]      0.6.3claws14
 
        * src/prefs_account.[ch], src/send.c, src/smtp.[ch]
index 986378651feb150e1f73f051ad9d79c1597e3a12..13d442afe48965862b6b4fe41c00ce66e2406326 100644 (file)
@@ -8,7 +8,7 @@ MINOR_VERSION=6
 MICRO_VERSION=3
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=claws14
+EXTRA_VERSION=claws15
 VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION$EXTRA_VERSION
 
 dnl
index e4f384548362575c44c7b88eac8edfed950cccfe..6b51ea343713530c75f0e18e3c1cf6fb75be12d4 100644 (file)
@@ -296,9 +296,7 @@ int main(int argc, char *argv[])
        /* ignore SIGPIPE signal for preventing sudden death of program */
        signal(SIGPIPE, SIG_IGN);
 
-       gdk_threads_enter();
        gtk_main();
-       gdk_threads_leave();
 
 #if USE_PSPELL       
        gtkpspell_finished(gtkpspellconfig);
index d0d1cf710f091140b0dea6527ece4c0fb6807b4f..0080549b8a0a476f16519880909914abb31dbc27 100644 (file)
@@ -68,6 +68,7 @@ SyldapServer *syldap_create() {
        ldapServer->retVal = MGU_SUCCESS;
        ldapServer->callBack = NULL;
        ldapServer->accessFlag = FALSE;
+       ldapServer->idleId = 0;
        return ldapServer;
 }
 
@@ -630,6 +631,19 @@ gint syldap_search( SyldapServer *ldapServer ) {
        return ldapServer->retVal;
 }
 
+/* syldap_display_search_results() - updates the ui. this function is called from the
+ * main thread (the thread running the GTK event loop). */
+static gint syldap_display_search_results(SyldapServer *ldapServer)
+{
+       /* NOTE: when this function is called the accompanying thread should 
+        * already be terminated. */
+       gtk_idle_remove(ldapServer->idleId);
+       ldapServer->callBack(ldapServer);
+       /* FIXME:  match should know whether to free this SyldapServer stuff.  */
+       g_free(ldapServer->thread); 
+       return TRUE;
+}
+
 /* ============================================================================================ */
 /*
 * Read data into list. Main entry point
@@ -654,13 +668,15 @@ gint syldap_read_data( SyldapServer *ldapServer ) {
        /* Callback */
        ldapServer->busyFlag = FALSE;
        if( ldapServer->callBack ) {
-               ( ldapServer->callBack )( ldapServer );
+               /* make the ui thread update the search results */
+               /* TODO: really necessary to call gdk_threads_XXX()??? gtk_idle_add()
+                * should do this - could someone check the GTK sources please? */
+               gdk_threads_enter();
+               ldapServer->idleId = gtk_idle_add(syldap_display_search_results, ldapServer);
+               gdk_threads_leave();
+       
        }
-       /* The thread struct should not be freed inside the thread
-       g_free(ldapServer->thread);
-       ldapServer->thread = NULL;
-       pthread_exit( NULL );
-       */
+
        return ldapServer->retVal;
 }
 
@@ -672,16 +688,13 @@ gint syldap_read_data( SyldapServer *ldapServer ) {
 void syldap_cancel_read( SyldapServer *ldapServer ) {
        g_return_if_fail( ldapServer != NULL );
 
+       /* DELETEME: this is called from inside UI thread so it's OK, Christoph! */
        if( ldapServer->thread ) {
                /* printf( "thread cancelled\n" ); */
-               /* The thread is cancleing itself, ok?
                pthread_cancel( *ldapServer->thread );
-               */
        }
-       /* The thread struct should not be freed inside the thread
        g_free(ldapServer->thread);
        ldapServer->thread = NULL;
-       */
        ldapServer->busyFlag = FALSE;
 }
 
@@ -702,7 +715,7 @@ gint syldap_read_data_th( SyldapServer *ldapServer ) {
 
                ldapServer->busyFlag = TRUE;
                ldapServer->thread = g_new0(pthread_t, 1);
-               pthread_create( ldapServer->thread, NULL, (void *) &syldap_read_data, (void *) ldapServer );
+               pthread_create( ldapServer->thread, NULL, (void *) syldap_read_data, (void *) ldapServer );
        }
        return ldapServer->retVal;
 }
index 9c2449d99115fc824703eba703102231b51b0856..c6e9d49a72e86370b10183e860daebfd8cd9ae7d 100644 (file)
@@ -65,6 +65,7 @@ struct _SyldapServer {
        pthread_t    *thread;
        gboolean     busyFlag;
        void         (*callBack)( void * );
+       guint        idleId;
 };
 
 /* Function prototypes */