On Mon, 12 Jan 2009 10:59:52 -0600, Ken Bloom wrote: > On Mon, 12 Jan 2009 10:34:26 -0500, Charles Oliver Nutter wrote: > >> Ken Bloom wrote: >>> Which reminds me of another question I had. You were discussing >>> somewhere else how Thread.critical works in JRuby. Does >>> Thread.critical / Thread.exclusive in JRuby protect other threads >>> against changes to the core class methods? Can I run >>> Thread.critical=true , dramatically redefine operators on the core >>> classes, redefine the operators back their original implementations, >>> run Thread.critical=false, and expect that no other JRuby thread can >>> get in and be broken becuase I've dramatically gutted the core >>> classes? >> >> You could up until about a week ago, when I proactively modified >> critical= to just be a reentrant global lock. So basically.. >> >> Before: >> * critical= causes the current thread to be the only thread running * >> ...except on JRuby where threads run in parallel and have to reach a >> checkpoint before they stop >> * ...or if code you call from within a critical section itself spins up >> threads >> >> After: >> >> * critical= acquires or releases a lock on a global mutex * threads >> that don't have critical sections continue running * threads that try >> to acquire the lock while another thread has it block >> >> This was actually proposed by Shri Borde of IronRuby and blogged here: >> >> http://blogs.msdn.com/shrib/archive/2009/01/07/proposed-spec-for-ruby- s- > thread-critical.aspx >> >> She (he?) proposes that almost all current uses of critical= intend to >> simply delimit a critical section of code, and so a single global mutex >> is sufficient for those cases. And in light of the fact that native >> calls and parallel-threaded impls can't be guaranteed to deschedule >> other threads, I think this is a much more concrete and reasonable >> definition. So I agreed, said so on a critical-related ruby-core >> thread, and went ahead with the change. Nothing has broken so far :) >> >> For your case, I think your best bet is to either make those changes >> before other threads start running or just accept that some of them >> won't see your changes all at once. I believe what you want to do may >> work on MRI, since it doesn't actually run threads in parallel and >> critical= stops it from scheduling new ones on its own. > > My goal is that other threads don't see the changes, by operating as > follows: > > In Ruby 1.8 pseudocode: > > old_critical=Thread.critical > begin > Thread.critical=true > > [Fixnum,String].each{|klass| override_methods_on klass} > result=builderblock.call > [Fixnum,String].each{|klass| restore_methods_on klass} > ensure > Thread.critical=old_critical > end > > Can I guarantee that other threads won't see my badly mangled Fixnum and > String? Or is there some possiblity that another thread would continue > executing and call (now badly broken) methods on Fixnum and String for a > while before it hit a checkpoint that made it hit the lock? From your > description it sounds like the latter is the case, in which case I need > to be looking at sandboxing solutions or warn people very loudly that > this part of the library is not thread safe and cannot be made thread > safe. (AIUI, there's also no standard way of sandboxing right now.) > >> But also note that critical= is gone in 1.9, so you should not use it >> anyway. Use a Mutex whenever possible...it's quick, easy, and safe. >> >> - Charlie > > In Ruby 1.9 pesudocode this is only slightly different: > > Thread.exclusive do > [Fixnum,String].each{|klass| override_methods_on klass} > result=builderblock.call > [Fixnum,String].each{|klass| restore_methods_on klass} > end > > (The methods being overridden in this case are pretty much any useful > binary operator on Fixnum and String, so this is pretty drastic, not to > mention that one of those operators is != which people have been > gripeing about a lot on ruby-core.) > > --Ken Oh, shoot. I just realized I'd have the same problem if code passed to the s-expression builder called user-defined custom methods (which is actually a desired behavior) to use their results. Those methods would be broken inside by the wretching monkey patching going on. I guess it's probably best to abandon the idea of the s-expression builder completely, or do it with a string, an explicit binding, and ripper. --Ken -- Chanoch (Ken) Bloom. PhD candidate. Linguistic Cognition Laboratory. Department of Computer Science. Illinois Institute of Technology. http://www.iit.edu/~kbloom1/