Class: Zoidberg::Signal

Inherits:
Object
  • Object
show all
Includes:
SoftShell
Defined in:
lib/zoidberg/signal.rb

Overview

Wait/send signals

Constant Summary collapse

EMPTY_VALUE =

empty value when no object is provided

:_zoidberg_empty_

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from SoftShell

#_zoidberg_thread, #async, #defer, included, #sleep

Constructor Details

#initialize(args = {}) ⇒ self

Create a new instance for sending and receiving signals

Parameters:

  • args (Hash) (defaults to: {})

    options



22
23
24
25
# File 'lib/zoidberg/signal.rb', line 22

def initialize(args={})
  @cache_signals = args.fetch(:cache_signals, false)
  @waiters = Smash.new
end

Instance Attribute Details

#cache_signals(arg = nil) ⇒ TrueClass, FalseClass (readonly)

Set cache behavior

Parameters:

  • arg (TrueClass, FalseClass) (defaults to: nil)

    set behavior

Returns:

  • (TrueClass, FalseClass)

    behavior



16
17
18
# File 'lib/zoidberg/signal.rb', line 16

def cache_signals
  @cache_signals
end

#waitersSmash (readonly)

Returns meta information on current waiters.

Returns:

  • (Smash)

    meta information on current waiters



14
15
16
# File 'lib/zoidberg/signal.rb', line 14

def waiters
  @waiters
end

Instance Method Details

#broadcast(signal, obj = EMPTY_VALUE) ⇒ TrueClass, FalseClass

Send a signal to all waiters

Parameters:

  • signal (Symbol)

    name of signal

  • obj (Object) (defaults to: EMPTY_VALUE)

    optional Object to send

Returns:

  • (TrueClass, FalseClass)

    if signal(s) was/were sent



57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/zoidberg/signal.rb', line 57

def broadcast(signal, obj=EMPTY_VALUE)
  if(signal_init(signal, :signal))
    num = waiters[signal][:threads].size
    num = 1 if num < 1
    num.times do
      waiters[signal][:queue].push obj
    end
    true
  else
    false
  end
end

#signal(signal, obj = EMPTY_VALUE) ⇒ TrueClass, FalseClass

Send a signal to one waiter

Parameters:

  • signal (Symbol)

    name of signal

  • obj (Object) (defaults to: EMPTY_VALUE)

    optional Object to send

Returns:

  • (TrueClass, FalseClass)

    if signal was sent



43
44
45
46
47
48
49
50
# File 'lib/zoidberg/signal.rb', line 43

def signal(signal, obj=EMPTY_VALUE)
  if(signal_init(signal, :signal))
    waiters[signal][:queue].push obj
    true
  else
    false
  end
end

#terminateObject

Force any waiter threads into an error state



84
85
86
87
88
89
90
# File 'lib/zoidberg/signal.rb', line 84

def terminate
  waiters.each do |k,v|
    v[:threads].each do |thread|
      thread.raise ::Zoidberg::DeadException.new('Instance in terminated state!', object_id)
    end
  end
end

#wait_for(signal) ⇒ Float

Wait for a signal

Parameters:

  • signal (Symbol)

    name of signal

Returns:

  • (Float)

    number of seconds waiting for signal



74
75
76
77
78
79
80
81
# File 'lib/zoidberg/signal.rb', line 74

def wait_for(signal)
  signal_init(signal, :wait)
  start_sleep = Time.now.to_f
  waiters[signal][:threads].push(Thread.current)
  val = defer{ waiters[signal][:queue].pop }
  waiters[signal][:threads].delete(Thread.current)
  val == EMPTY_VALUE ? (Time.now.to_f - start_sleep) : val
end