Class: Thread

Inherits:
Object show all
Defined in:
lib/polyphony/extensions/thread.rb

Overview

Thread extensions

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args, &block) ⇒ Thread

Initializes the thread.

Parameters:

  • args (Array)

    arguments to pass to thread block



15
16
17
18
19
20
# File 'lib/polyphony/extensions/thread.rb', line 15

def initialize(*args, &block)
  @join_wait_queue = []
  @args = args
  @block = block
  orig_initialize { execute }
end

Instance Attribute Details

#backendObject

Returns the value of attribute backend.



8
9
10
# File 'lib/polyphony/extensions/thread.rb', line 8

def backend
  @backend
end

#main_fiberObject (readonly)

Returns the value of attribute main_fiber.



7
8
9
# File 'lib/polyphony/extensions/thread.rb', line 7

def main_fiber
  @main_fiber
end

#resultObject (readonly)

Returns the value of attribute result.



7
8
9
# File 'lib/polyphony/extensions/thread.rb', line 7

def result
  @result
end

Class Method Details

.backendPolyphony::Backend

Returns the backend for the current thread.

Returns:

  • (Polyphony::Backend)

    backend for the current thread



85
86
87
# File 'ext/polyphony/thread.c', line 85

VALUE Thread_class_backend(VALUE _self) {
  return rb_ivar_get(rb_thread_current(), ID_ivar_backend);
}

Instance Method Details

#<<(msg) ⇒ Fiber Also known as: send

Sends a message to the thread's main fiber.

Parameters:

  • msg (any)

    message

Returns:



98
99
100
# File 'lib/polyphony/extensions/thread.rb', line 98

def <<(msg)
  main_fiber << msg
end

#await_doneObject



126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'ext/polyphony/thread.c', line 126

VALUE Thread_await_done(VALUE self)
{
  if (Thread_done_p(self) == Qtrue) return rb_ivar_get(self, ID_ivar_result);

  VALUE waiter = Fiber_auto_watcher(rb_fiber_current());
  VALUE waiters = rb_ivar_get(self, ID_ivar_waiters);
  if (waiters == Qnil) {
    waiters = rb_ary_new();
    rb_ivar_set(self, ID_ivar_waiters, waiters);
  }
  rb_ary_push(waiters, waiter);

  return Event_await(waiter);
}

#done?Boolean

Returns:

  • (Boolean)


90
91
92
93
# File 'ext/polyphony/thread.c', line 90

VALUE Thread_done_p(VALUE self)
{
  return rb_ivar_get(self, ID_ivar_done);
}

#fiber_unschedule(fiber) ⇒ Thread

Removes the given fiber from the thread's runqueue.

Parameters:

  • fiber (Fiber)

    fiber to unschedule

Returns:



31
32
33
34
# File 'ext/polyphony/thread.c', line 31

VALUE Thread_fiber_unschedule(VALUE self, VALUE fiber) {
  Backend_unschedule_fiber(rb_ivar_get(self, ID_ivar_backend), fiber);
  return self;
}

#idle_gc_period=(period) ⇒ Number

Sets the idle GC period for the thread's backend.

Parameters:

  • period (Number)

    GC period in seconds

Returns:

  • (Number)

    GC period



107
108
109
# File 'lib/polyphony/extensions/thread.rb', line 107

def idle_gc_period=(period)
  backend.idle_gc_period = period
end

#inspectString Also known as: to_s

Returns a string representation of the thread for debugging purposes.

Returns:

  • (String)

    string representation



79
80
81
82
83
84
# File 'lib/polyphony/extensions/thread.rb', line 79

def inspect
  return orig_inspect if self == Thread.main

  state = status || 'dead'
  "#<Thread:#{object_id} #{location} (#{state})>"
end

#join(timeout = nil) ⇒ any Also known as: await

Waits for the thread to terminate and returns its return value. If the thread terminated with an uncaught exception, it is propagated to the waiting fiber. If a timeout interval is specified, the thread will be terminated without propagating the timeout exception.

Parameters:

  • timeout (Number) (defaults to: nil)

    timeout interval

Returns:

  • (any)

    thread's return value



42
43
44
# File 'lib/polyphony/extensions/thread.rb', line 42

def join(timeout = nil)
  timeout ? move_on_after(timeout) { await_done } : await_done
end

#kill_safeObject Also known as: kill



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'ext/polyphony/thread.c', line 95

VALUE Thread_kill_safe(VALUE self)
{
  static VALUE eTerminate = Qnil;
  if (rb_ivar_get(self, ID_ivar_done) == Qtrue) return self;

  if (eTerminate == Qnil)
    eTerminate = rb_const_get(mPolyphony, rb_intern("Terminate"));

  while (rb_ivar_get(self, ID_ivar_ready) != Qtrue)
    rb_thread_schedule();

  VALUE main_fiber = rb_ivar_get(self, ID_ivar_main_fiber);
  VALUE exception = rb_funcall(eTerminate, ID_new, 0);
  Thread_schedule_fiber(self, main_fiber, exception);
  return self;
}

#locationString

Returns the source location of the thread's block.

Returns:

  • (String)

    source location



90
91
92
# File 'lib/polyphony/extensions/thread.rb', line 90

def location
  @block.source_location.join(':')
end

#mark_as_done(result) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'ext/polyphony/thread.c', line 112

VALUE Thread_mark_as_done(VALUE self, VALUE result)
{
  rb_ivar_set(self, ID_ivar_done, Qtrue);
  VALUE waiters = rb_ivar_get(self, ID_ivar_waiters);
  if (waiters == Qnil) return self;

  int len = RARRAY_LEN(waiters);
  for (int i = 0; i < len; i++) {
    VALUE waiter = RARRAY_AREF(waiters, i);
    Event_signal(1, &result, waiter);
  }
  return self;
}

#on_idle(&block) ⇒ Proc

Sets the idle handler for the thread's backend.

Returns:

  • (Proc)

    idle handler



114
115
116
# File 'lib/polyphony/extensions/thread.rb', line 114

def on_idle(&block)
  backend.idle_proc = block
end

#raise(error = nil) ⇒ Object

Raises an exception in the context of the thread. If no exception is given, a RuntimeError is raised.

Parameters:

  • error (Exception, Class, nil) (defaults to: nil)

    exception spec



54
55
56
57
58
59
60
61
62
63
# File 'lib/polyphony/extensions/thread.rb', line 54

def raise(error = nil)
  sleep 0.0001 until @ready

  error = Exception.instantiate(error)
  if Thread.current == self
    Kernel.raise(error)
  else
    @main_fiber&.raise(error)
  end
end

#setupThread

Sets up the thread and its main fiber.

Returns:



25
26
27
28
29
30
# File 'lib/polyphony/extensions/thread.rb', line 25

def setup
  @main_fiber = Fiber.current
  @main_fiber.setup_main_fiber
  setup_fiber_scheduling
  self
end

#setup_fiber_schedulingObject

:nop-doc:



16
17
18
19
# File 'ext/polyphony/thread.c', line 16

static VALUE Thread_setup_fiber_scheduling(VALUE self) {
  rb_ivar_set(self, ID_ivar_main_fiber, rb_fiber_current());
  return self;
}

#switch_fiberany

Switches to the next fiber in the thread's runqueue.

Returns:

  • (any)

    resume value



53
54
55
# File 'ext/polyphony/thread.c', line 53

VALUE Thread_switch_fiber(VALUE self) {
  return Backend_switch_fiber(rb_ivar_get(self, ID_ivar_backend));
}

#valueObject



118
119
120
121
# File 'lib/polyphony/extensions/thread.rb', line 118

def value
  join
  @result.is_a?(Exception) ? raise(@result) : @result
end