Class: Puppet::Parser::TypeLoader::Helper

Inherits:
Object
  • Object
show all
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

Constructor Details

#initializeHelper

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