[Evolution-hackers] Hang in e_book_new when multiple threads are	involved
- From: Joshua Cranmer <Pidgeot18 verizon net>
- To: evolution-hackers gnome org
- Subject: [Evolution-hackers] Hang in e_book_new when multiple threads are	involved
- Date: Mon, 18 May 2009 21:15:38 -0400
I was told by Muelli over IRC that I should post this to the hackers list.
In some of the code I'm writing for Mozilla, I noticed that one set of 
circumstances caused the code to hang in e_book_new. When I run the 
e_book_new in a brand new thread under the testing environment, the code 
would just hang. If I did it under regular UI environment or ran it in 
the same thread, the hang disappeared. I am currently using the 2.24 
version of Evolution that is provided under Debian testing.
Here is some code that demonstrates the problem (a rather small test 
case mimicking the conditions):
#include <libebook/e-book.h>
#include <libedataserver/e-source-list.h>
#include <pthread.h>
#include <iostream>
using namespace std;
void *handle_source(void *source);
ESourceList *sources;
int main() {
   g_type_init();
   GConfClient *gconf = gconf_client_get_default();
   sources = e_source_list_new_for_gconf(gconf, 
"/apps/evolution/addressbook/sources");
   GSList *groups = e_source_list_peek_groups(sources);
   char *uid = NULL;
   for (;groups;groups = groups->next) {
       ESourceGroup *group = E_SOURCE_GROUP(groups->data);
       if (!group) continue;
       GSList *sources = e_source_group_peek_sources(group);
       for (; sources; sources = sources->next) {
           ESource *source = E_SOURCE(sources->data);
           uid = (char *)e_source_peek_uid(source);
           goto end;
       }
   }
end:
   pthread_attr_t threadAttrs;
   pthread_attr_init(&threadAttrs);
   pthread_t thread;
   pthread_create(&thread, &threadAttrs, handle_source, uid);
   pthread_join(thread, NULL);
}
void *handle_source(void *source2) {
   ESource *source = e_source_list_peek_source_by_uid(sources, (const 
char *)source2);
   cout << "Before new\n";
   EBook *book = e_book_new(source, NULL);
   cout << "After new\n";
   if (!e_book_open(book, true, NULL)) {
       return (void*)1;
   }
   GList *contacts;
   if (!e_book_get_contacts(book, e_book_query_any_field_contains(""), 
&contacts, NULL)) {
       cout << "Can't get contacts!\n";
   }
   cout << g_list_length(contacts) << endl;
   return 0;
}
jcranmer quetzalcoatal ~/evolution $ make
g++ -g -o evolution-test -I/usr/include/evolution-data-server-2.24 
-I/usr/include/evolution-data-server-2.24 -I/usr/lib/glib-2.0/include 
-I/usr/include/libxml2 -I/usr/include/gconf/2 -I/usr/include/glib-2.0 
-ledataserver-1.2 -lebook-1.2 -pthread test2.cpp
jcranmer quetzalcoatl ~/evolution $ ./evolution-test
Before new
If you change the pthread code to directly call handle_source(uid), you 
get the expected results:
jcranmer quetzalcoatl ~/evolution $ ./evolution-test
Before new
After new
1
Hopefully, this should be enough information to have other people 
reproduce the issue.
--
Beware of bugs in the above code; I have only proved it correct, not tried it. -- Donald E. Knuth
[
Date Prev][
Date Next]   [
Thread Prev][
Thread Next]   
[
Thread Index]
[
Date Index]
[
Author Index]