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