Class: Puppet::Parser::TypeLoader::Helper
- Includes:
- MonitorMixin
- Defined in:
- lib/vendor/puppet/parser/type_loader.rb
Overview
Helper class that makes sure we don’t try to import the same file more than once from either the same thread or different threads.
Instance Method Summary collapse
-
#do_once(file) ⇒ Object
Execute the supplied block exactly once per file, no matter how many threads have asked for it to run.
-
#initialize ⇒ Helper
constructor
A new instance of Helper.
Constructor Details
#initialize ⇒ Helper
Returns a new instance of Helper.
11 12 13 14 15 16 17 |
# File 'lib/vendor/puppet/parser/type_loader.rb', line 11 def initialize super # These hashes are indexed by filename @state = {} # :doing or :done @thread = {} # if :doing, thread that's doing the parsing @cond_var = {} # if :doing, condition var that will be signaled when done. end |
Instance Method Details
#do_once(file) ⇒ Object
Execute the supplied block exactly once per file, no matter how many threads have asked for it to run. If another thread is already executing it, wait for it to finish. If this thread is already executing it, return immediately without executing the block.
Note: the reason for returning immediately if this thread is already executing the block is to handle the case of a circular import–when this happens, we attempt to recursively re-parse a file that we are already in the process of parsing. To prevent an infinite regress we need to simply do nothing when the recursive import is attempted.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/vendor/puppet/parser/type_loader.rb', line 31 def do_once(file) need_to_execute = synchronize do case @state[file] when :doing if @thread[file] != Thread.current @cond_var[file].wait end false when :done false else @state[file] = :doing @thread[file] = Thread.current @cond_var[file] = new_cond true end end if need_to_execute begin yield ensure synchronize do @state[file] = :done @thread.delete(file) @cond_var.delete(file).broadcast end end end end |