class Asynchronous::Thread

Public Class Methods

new(&callable) click to toggle source
# File lib/asynchronous/thread.rb, line 2
def initialize(&callable)
  @value = nil
  @value_received = false
  @read, @write = ::IO.pipe
  read_buffer

  @pid = fork(&callable)
end

Public Instance Methods

join() click to toggle source
# File lib/asynchronous/thread.rb, line 11
def join
  wait
  receive_value! unless @value_received
  raise(@value.wrapped_error) if @value.is_a?(::Asynchronous::Error)
  self
end
kill() click to toggle source
# File lib/asynchronous/thread.rb, line 18
def kill
  ::Process.kill('KILL', @pid)

  wait
rescue Errno::ESRCH
  nil
end
status() click to toggle source
# File lib/asynchronous/thread.rb, line 26
def status
  alive? ? 'run' : false
end
value() click to toggle source
# File lib/asynchronous/thread.rb, line 30
def value
  join; @value
end

Protected Instance Methods

alive?() click to toggle source
# File lib/asynchronous/thread.rb, line 36
def alive?
  ::Asynchronous::Utils.alive?(@pid)
end
fork(&callable) click to toggle source
# File lib/asynchronous/thread.rb, line 53
def fork(&callable)
  ::Kernel.fork { main(&callable) }
end
main() { || ... } click to toggle source
# File lib/asynchronous/thread.rb, line 63
def main
  ::Asynchronous::ZombiKiller.antidote

  @read.close

  result = begin
    yield
  rescue ::Exception => ex
    ::Asynchronous::Error.new(ex)
  end

  write_result!(result)
end
read_buffer() click to toggle source
# File lib/asynchronous/thread.rb, line 57
def read_buffer
  @read_buffer ||= ::Thread.new do
    @value = Marshal.load(@read)
  end
end
receive_value!() click to toggle source
# File lib/asynchronous/thread.rb, line 40
def receive_value!
  @write.close
  read_buffer.join
  @read.close
  @value_received = true
end
wait(flag = 0) click to toggle source
# File lib/asynchronous/thread.rb, line 47
def wait(flag = 0)
  ::Process.wait(@pid, flag)
rescue Errno::ECHILD
  nil
end
write_result!(result) click to toggle source
# File lib/asynchronous/thread.rb, line 77
def write_result!(result)
  return unless Asynchronous::ZombiKiller.how_is_mom?
  ::Marshal.dump(result, @write)
  @write.flush
  @write.close
rescue Errno::EPIPE
  nil
end