On Sat, 4 Jan 2014 02:22:11 +0100 Panicz Maciej Godek <godek.mac...@gmail.com> wrote: > I concluded that this might be a solution. I tested it with 2.0.5 from > ubuntu repository. I had to add GC_allow_register_threads (and link > against gc, accordingly), because otherwise the program aborted with > the message "Threads explicit registering is not previously enabled" > whenever it attempted to create a thread. > > For some reason the initialization routine needs to call > scm_c_eval_string; otherwise it doesn't help. > > The solution doesn't fill me with joy, but I hope it works for you
Cool. Your revised test case appears to work on guile-2.0.9 without calling GC_allow_register_threads(). Subject to further testing the key seems to be to allow one thread to complete a call to scm_with_guile() and scm_c_eval_string() before any new one is allowed to do anything. On further testing (involving inserting my own synchronization and using scm_init_guile()) it appears that none of scm_with_guile(), scm_init_guile() and scm_c_eval_string() are thread safe on the first call. They seem to do some initial set up on first call which is not done in a thread safe way. By way of example, for me this also works (does it work for guile-2.0.5?): #include <libguile.h> #include <pthread.h> void *guile_wrapper (void *data) { scm_c_eval_string ("(display \"Hello\n\")"); return NULL; } void *thread_func (void *data) { scm_with_guile (&guile_wrapper, NULL); return NULL; } int main () { pthread_t thread1; pthread_t thread2; pthread_t thread3; /* initialize */ pthread_create (&thread1, NULL, thread_func, NULL); pthread_join (thread1, NULL); /* proceed with other threads */ pthread_create (&thread2, NULL, thread_func, NULL); pthread_create (&thread3, NULL, thread_func, NULL); pthread_join (thread2, NULL); pthread_join (thread3, NULL); return 0; } Unfortunately, from what Mark Weaver says, the module system doesn't initialize itself in a thread safe way either :(. That is more problematic because you might not know in advance what modules are to be loaded by any particular code. The task model isn't suppose to import cross-dependencies of that kind. Chris