From: Dave Thomas Date: 2008-12-24T08:04:31+09:00 Subject: [ruby-core:20849] Re: [Bug #921] autoload is not thread-safe On Dec 23, 2008, at 4:16 PM, Charles Oliver Nutter wrote: >> Yeah--you'd need to make require transactional somehow. > > Yeah, that's essentially it (though it's more specific to autoload). > You'd need to lock the constant under autoload in such a way that > other threads would block until autoloading completed. And unless it > were a single global lock for all autoload logic, there's a strong > potential for deadlock if two threads encounter opposing constants > at the same time. Would it be sufficient to add field to each constant to say "loading in progress in thread n" Have the lock we've been talking about in autoload and require. During require, set the current thread id into every newly defined constant, keeping a list of the ones that are set. Maintain a stack of the current requires. (These will all be in the same thread because of the mutex). When the last require finishes, go though all constants in the list and unset the thread id in them. Finally, signal a condition variable. Constant lookup then works like this: If the constant isn't defined, claim the require mutex and then check for autoloading stuff. If the constant is defined, check to see if the thread id is set in the constant. If it is, wait on the condition variable. That way, you won't pick up partially initialized constants that are being autoloaded or required by other threads. And, I know, this sounds ridiculously complex. But the only alternative I see is locking the entire interpreter during requires. Dave