2 # Channel is a FIFO, thread-aware value passing class that can hold any number
3 # of objects similar to Queue. Use #send to add objects to the channel and
4 # #receive to remove objects from the channel.
6 # If Channel#receive is called on an empty channel, the VM puts the current
7 # Thread (t1) to sleep. At some future time, when Channel#send is called on
8 # that same thread, the VM wakes up t1 and the value passed to #send is
9 # returned. This allows us to implement all manner of Thread semantics, such
12 # Channel is used heavily by Scheduler, to allow ruby code to interact with
13 # the outside world in a thread aware manner.
17 ivar_as_index :waiting => 1, :value => 2
20 # Returns nil if nothing is waiting, or a List object which contains all
21 # Thread objects waiting on this Channel.
23 def waiting() @waiting end
26 # Returns nil if there are no values, otherwise a List object containing all
27 # values the Channel contains.
29 def value() @value end
32 # Creates a new Channel and registers it with the VM.
35 Ruby.primitive :channel_new
36 raise PrimitiveFailure, "primitive failed"
40 # Puts +obj+ in the Channel. If there are waiting threads the first thread
41 # will be woken up and handed +obj+.
44 Ruby.primitive :channel_send
45 raise PrimitiveFailure, "primitive failed"
49 # Removes and returns the first value from the Channel. If the channel
50 # is empty, Thread.current is put to sleep until #send is called.
53 Ruby.primitive :channel_receive
54 raise PrimitiveFailure, "primitive failed"
58 # Converts +obj+ into a Channel using #to_channel.
60 def self.convert_to_channel(obj)
61 return obj if Channel === obj
65 raise ArgumentError, "to_channel on #{obj.inspect} did not return a Channel"
69 raise ArgumentError, "Unable to convert #{obj.inspect} into a channel"
74 # Legacy API. To be removed.
76 def self.receive(obj) # :nodoc:
77 return convert_to_channel(obj).receive
81 # API compliance, returns self.