Robert Klemme wrote: > 2008/12/21 Charles Oliver Nutter <charles.nutter / sun.com>: >> Gary Wright wrote: >>> I admit to not thinking about this too much but shouldn't there be a >>> global lock on things like require and load? If it isn't enforced by Ruby >>> itself, I would think that a properly designed multi-threaded application >>> shouldn't have multiple threads contending for access to global state >>> without proper locking. >> It certainly could, but that is a behavioral change; there's no way to >> require files in separate threads at the same time. Of course, maybe it's a >> bad idea to allow that in the first place. > > I don't think there should be locking involved for "load" as that > loads a file unconditionally. When using "load" one must be aware of > the fact that the file can be loaded multiple times - including > concurrently. I tend to agree. Load explicitly bypasses things like $" population so you can load the same file repeatedly if you want to. So I think load should be the lock-free low-level "always execute target file" version. And in truth, require is largely implemented in terms of load. > For "require" the story looks a bit different. If I am not mistaken > you would need a reentrant lock per (case insensitive? - probably > depending on file system) string after "require" as the smallest > granularity. Hm... The longer I think about it the more I believe > that a single reentrant lock for "require" is probably the most robust > solution... I think it has to be a single lock or nothing, due to the deadlock possibilities of a lock-per-resources. So I'll summarize my position here: - requires cannot safely be done concurrently because they will cause resources (classes, modules) to be accessed before they are completely loaded and initialized. - The simplest solution for this is to not require resources concurrently, which is certainly a valid solution which requires no locks and no behavioral changes. - A lock per resources or per name is broken, due to deadlock potential, and so is not the right solution - A single global lock would fix require concurrency (and almost be enough to fix autoload concurrency) but would introduce the behavioral change that only one require can execute at a time. - I'm not strongly leaning toward either "no fix" or a global require lock. It doesn't bother me terrible that require isn't thread-safe, since the simple fix of "don't do that" solve the problem without complication. > While we're at it: what happens to "require" in light of changes to $: > and current directory? I don't think it would make any difference; both just change how it searches for files, and should not affect concurrency characteristics. - Charlie