Prezi

Present Remotely

Send the link below via email or IM

Copy

Present to your audience

Start remote presentation

  • Invited audience members will follow you as you navigate and present
  • People invited to a presentation do not need a Prezi account
  • This link expires 10 minutes after you close the presentation
  • A maximum of 30 users can follow your presentation
  • Learn more about this feature in the manual

Do you really want to delete this prezi?

Neither you, nor the coeditors you shared it with will be able to recover it again.

DeleteCancel

Make your likes visible on Facebook?

Connect your Facebook account to Prezi and let your likes appear on your timeline.
You can change this under Settings & Account at any time.

No, thanks

Making autoload thread-safe

Prezi for Asakusa.rb meetup #114 at 2011-07-19
by Hiroshi Nakamura on 19 July 2011

Comments (0)

Please log in to add your comment.

Report abuse

Transcript of Making autoload thread-safe

Making autoload thread-safe Feature loading in Ruby
Concurrency issues
How autoload works
Making autoload thread-safe 2 ways of feature loading
(find, load and exec a file) require ... loads feature w/ double loading protection

autoload ... calls 'require' at the first constant lookup for lazy feature loading Concurrency issues require





autoload Thread-safe (serialized) (OK)
circular require is warned but (OK)
deadlock by cross require (!)



Thread-unsafe (!) autoload concurrency issue safe: accessing the constant itself




unsafe: accesing inner resources autoload |module Gem
| VERSION = '1.8.5.1'
| ...
| autoload :Version, 'rubygems/version'
| autoload :Requirement, 'rubygems/requirement'
| autoload :Dependency, 'rubygems/dependency'
| autoload :Specification, 'rubygems/specification'
| ... require 'rubygems' # it runs at startup

require 'httpclient' # user code
-> custom 'require' in rubygems/custom_require.rb
-> spec = Gem::Specification.find {...}
-> require "rubygems/specification" autoload :C, "c"
t1 = Thread.new { C }
t2 = Thread.new { C }
[t1, t2].each(&:join) autoload :D, "d"
t1 = Thread.new { D::X }
t2 = Thread.new { D.d }
[t1, t2].each(&:join) What's happened? |class Module
| def autoload(symbol, feature)
| self.autoload[symbol] = feature
| self.const[symbol] = UNDEF
| nil
| end
|
| def _get_constant(symbol)
| obj = self.const[symbol]
| return obj if obj != UNDEF
| require(self.autoload.delete(symbol))
| self.const[symbol]
| end
| ... What's wrong? p D::X

(const[:D] == UNDEF)

(start require "d")

module D # const[:D] = newmod




def D.d # Too late p D.d


(const[:D] != UNDEF)

(call newmod.d) Thread: t1 Thread: t2 Making autoload thread-safe Here's my try;
let Module keep 'UNDEF' in constant map until the end of autoloading
let Module keep actual object in another map (autoloading map)
add extra check for constant lookup JRuby: http://jira.codehaus.org/browse/JRUBY-3194 by @wycats 2008-11-28
CRuby: http://redmine.ruby-lang.org/issues/921 by @headius 2008-12-23 Sample implementation Summary autoload is not thread-safe ATM

Would be fixed in JRuby > Tom?

Might be fixed in CRuby? > Sasada-san?

Rubinius? > ? "Thread"
th-re'd | def _get_constant(symbol)
| if self.const[symbol] == UNDEF
| autoloading = self.autoloading[symbol]
| if autoloading.thread == Thread.current
| return autoloading.value
| end
| require(self.autoload.delete(symbol))
| ... In JRuby only






No perf drop CRuby prefer processes/MVMs rather than threads so we may remove 'autoload'?
JRuby goes with threads so autoload must be thread-safe.



Extra-checks are needed only while autoloading.
General constant lookups are not affected. We need a training Overrides UNDEF! https://github.com/jruby/jruby/tree/autoload-threadsafe How autoload works Accessing 'D' should be allowed only from the current thread NoMethodError! DEMO DEMO DEMO Hiroshi Nakamura
@nahi
C/JRuby committer
This slide => http://bit.ly/autoload
See the full transcript