Subj : Re: Threads and different SpiderMonkey Runtimes To : netscape.public.mozilla.jseng From : Wan-Teh Chang Date : Mon Oct 03 2005 06:03 pm Mads Bondo Dydensborg wrote: > Mads Bondo Dydensborg skrev: > >> Hi >> >> I have a problem with using SpiderMonkey in my multithreaded C++ program. > > > It seems my problem might be related to the nspr library. > > Iff I make sure that a threads has initialized the nspr library fully, > before starting up all my other threads, I can run 3500 concurrent > runtimes, each running their own contexts, objects and scripts without > problems. (More than 3500 threads breaks my system because I only have > 32 bit of virtual addressing, but that will not be a problem in practice). > > I have looked at the nspr code (pthread version, which is what I use), > and it seems that the reason I did have problems, was because of races > to the code in _PR_InitThreads. As long as I make sure that a single > thread gets to call this code (possibly other pieces as well), before > spawning all my other threads, things work out fine. Perhaps the > lazy/implicit initialization of nspr (pthread version) needs to be > wrapped in a call to pthread_once. > > My workaround is to run a single thread using a dummy javascript. It > would be nice to not have to do that, though. I believe your understanding is correct. NSPR was originally designed for applications that use NSPR. This is why the automatic implicit initialization of NSPR can be done in a thread-unsafe way, because it was assumed that the application would create threads using PR_CreateThread, which would cause NSPR to be initialized while the process is still single-threaded. Later, non-NSPR-based applications started to use NSPR-based libraries, and in general NSPR has worked well in these environments. But as you have found out, if multiple threads that are not created by NSPR call NSPR functions at the same time, they will all cause NSPR initialization function to be called, and you will hit the thread-unsafe problem. The workarounds include: 1. use PR_CreateThread to create the threads; or 2. call PR_Init to initialize NSPR explicitly before your threads call any NSPR function (I believe this is basically your workaround). Longer term, we should make NSPR initialization thread-safe by using pthread_once (which doesn't exist on non-Unix platforms) or shared library/DLL's initialization function (which is available on many platforms). Until this is done, you will need to use a workaround to cause NSPR to be initialized while your process only has one thread or before the other threads can start using NSPR. Sorry for the inconvenience. Wan-Teh .