File: event.rb

package info (click to toggle)
ruby-concurrent 1.1.6%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 30,284 kB
  • sloc: ruby: 30,875; java: 6,117; javascript: 1,114; ansic: 288; makefile: 10; sh: 6
file content (109 lines) | stat: -rw-r--r-- 2,830 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
require 'thread'
require 'concurrent/synchronization'

module Concurrent

  # Old school kernel-style event reminiscent of Win32 programming in C++.
  #
  # When an `Event` is created it is in the `unset` state. Threads can choose to
  # `#wait` on the event, blocking until released by another thread. When one
  # thread wants to alert all blocking threads it calls the `#set` method which
  # will then wake up all listeners. Once an `Event` has been set it remains set.
  # New threads calling `#wait` will return immediately. An `Event` may be
  # `#reset` at any time once it has been set.
  #
  # @see http://msdn.microsoft.com/en-us/library/windows/desktop/ms682655.aspx
  # @example
  #   event = Concurrent::Event.new
  #
  #   t1 = Thread.new do
  #     puts "t1 is waiting"
  #     event.wait(1)
  #     puts "event ocurred"
  #   end
  #
  #   t2 = Thread.new do
  #     puts "t2 calling set"
  #     event.set
  #   end
  #
  #   [t1, t2].each(&:join)
  #
  #   # prints:
  #   # t2 calling set
  #   # t1 is waiting
  #   # event occurred
  class Event < Synchronization::LockableObject

    # Creates a new `Event` in the unset state. Threads calling `#wait` on the
    # `Event` will block.
    def initialize
      super
      synchronize { ns_initialize }
    end

    # Is the object in the set state?
    #
    # @return [Boolean] indicating whether or not the `Event` has been set
    def set?
      synchronize { @set }
    end

    # Trigger the event, setting the state to `set` and releasing all threads
    # waiting on the event. Has no effect if the `Event` has already been set.
    #
    # @return [Boolean] should always return `true`
    def set
      synchronize { ns_set }
    end

    def try?
      synchronize { @set ? false : ns_set }
    end

    # Reset a previously set event back to the `unset` state.
    # Has no effect if the `Event` has not yet been set.
    #
    # @return [Boolean] should always return `true`
    def reset
      synchronize do
        if @set
          @set       = false
          @iteration +=1
        end
        true
      end
    end

    # Wait a given number of seconds for the `Event` to be set by another
    # thread. Will wait forever when no `timeout` value is given. Returns
    # immediately if the `Event` has already been set.
    #
    # @return [Boolean] true if the `Event` was set before timeout else false
    def wait(timeout = nil)
      synchronize do
        unless @set
          iteration = @iteration
          ns_wait_until(timeout) { iteration < @iteration || @set }
        else
          true
        end
      end
    end

    protected

    def ns_set
      unless @set
        @set = true
        ns_broadcast
      end
      true
    end

    def ns_initialize
      @set       = false
      @iteration = 0
    end
  end
end