lib/logstash-docket/util/threadsafe_deferral.rb (27 lines of code) (raw):

# encoding: utf-8 require 'thread' # Mutex module LogstashDocket module Util ## # A {@link ThreadsafeDeferral} ensures that the provided block is # executed at-most-once, if and when the value of the deferral is # requested. class ThreadsafeDeferral ## # Captures the block for later execution if and when its value is requested. # # @yieldreturn [Object] def self.for(&generator) new(generator) end private_class_method :new def initialize(generator) @generator = generator @generated = false @result = nil @mutex = Mutex.new end ## # returns the value of this deferral, generating it if necessary # # @return [Object] def value # return the value if it has been generated, # or attempt to generate it. @generated ? @result : @mutex.synchronize do # return the value if the value was generated before # we acquired the lock (e.g., another thread won) @generated ? @result : begin result = @generator.call @generator = nil @generated = true @result = result end end end end end end