free_mutant/lib/mutant/actor/receiver.rb
Markus Schirp d8e6805206 Fix actor race condition
* Use the `ConditionVariable` primitive to fix rece between stopped
  receiver Thread and its wake signal.
* Race was only observable via synthetical benchmarks and explicit
  sleeps between unlocking receiver mutex and Thread.stop
* Simplifies code a lot as thread must not be passed around anymore
2014-12-06 04:37:20 +00:00

46 lines
953 B
Ruby

module Mutant
module Actor
# Receiver side of an actor
class Receiver
include Adamantium::Flat, Concord.new(:condition_variable, :mutex, :messages)
# Receives a message, blocking
#
# @return [Object]
#
# @api private
#
def call
2.times do
message = try_blocking_receive
return message unless message.equal?(Undefined)
end
fail ProtocolError
end
private
# Try a blocking receive
#
# @return [Undefined]
# if there is no message yet
#
# @return [Object]
# if there is a message
#
# @api private
#
def try_blocking_receive
mutex.synchronize do
if messages.empty?
condition_variable.wait(mutex)
Undefined
else
messages.shift
end
end
end
end # Receiver
end # Actor
end # Mutant