wires 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/wires/hub.rb +79 -20
  3. data/lib/wires/time.rb +4 -5
  4. metadata +6 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 40c67db203689c9ec0f32d844252da5fd125d0b6
4
- data.tar.gz: 9d27b886a47150a99e68d1e10f7d0e9cc4550b31
3
+ metadata.gz: ed473de572f57451505cf39568dc498f6b2055fc
4
+ data.tar.gz: 6c6a3f80746359292cd22dd84c26c29b90957ef7
5
5
  SHA512:
6
- metadata.gz: a3d64df40e1a6ae3e73a8534a9a2955df9462eae21ba54119ff4b9be1ba775fc1b490497b824c3030f75d32356fd05592f1cb86d4143c7a2492a672b4480d37e
7
- data.tar.gz: b801be4fd8e4ad7d6d90a45575c5b865e052a3d11de7267db4f5c4fac3ea482b5e8e22b35e6db87bad5811eba6e3af2ff9ef564c802195a5a5e38f42648ebd74
6
+ metadata.gz: a2c40457ba7ecc2f8120e723fa3a3a13788ffd53c438b55d477c96f32336ec39c7a66cd7e08c7c0d27598c5725a205902e86866c725f5a99503d1aefa70765dd
7
+ data.tar.gz: d8e3993a55c2b6f4060d0ee1d7fd4df75af8a6ee64d0be1be40a8fc30d15d71fe26d5c18f927526cbaa6bb286d7520014fb674fb3c5606b913143c7c673533fe
data/lib/wires/hub.rb CHANGED
@@ -14,17 +14,34 @@ module Wires
14
14
  @queue = Queue.new
15
15
 
16
16
  @child_threads = Array.new
17
- @child_threads_lock = Mutex.new
17
+ @child_threads_lock = Monitor.new
18
18
 
19
+ @before_runs = Queue.new
20
+ @after_runs = Queue.new
19
21
  @before_kills = Queue.new
20
22
  @after_kills = Queue.new
21
23
 
22
24
  @please_finish_all = false
23
25
  @please_kill = false
24
26
 
27
+ @at_exit = Proc.new{nil}
28
+ at_exit do self.at_exit_proc end
29
+
30
+ @fire_proc_alive = Proc.new do |x|
31
+ @queue << [x, Thread.current]
32
+ @thread.wakeup
33
+ sleep
34
+ end
35
+ @fire_proc_dead = Proc.new do |x|
36
+ @queue << [x, nil]
37
+ end
38
+ @fire_proc = @fire_proc_dead
39
+
25
40
  state_machine_init
26
41
  nil end
27
42
 
43
+ def at_exit_proc; @at_exit.call; end
44
+
28
45
  # Make subclasses call class_init
29
46
  def inherited(subcls)
30
47
  subcls.class_init
@@ -37,7 +54,7 @@ module Wires
37
54
  # Start the Hub event loop (optional flags change thread behavior)
38
55
  #
39
56
  # valid flags:
40
- # [+:blocking+] Hub event loop will be run in calling thread,
57
+ # [+:in_place+] Hub event loop will be run in calling thread,
41
58
  # blocking until Hub is killed. If this flag is not
42
59
  # specified, the Hub event loop is run in a new thread,
43
60
  # which the main thread joins in at_exit.
@@ -45,9 +62,9 @@ module Wires
45
62
  request_state :alive until alive?
46
63
 
47
64
  # If :blocking, block now, else block at exit
48
- (flags.include? :blocking) ?
49
- (join_hegemon_auto_thread) :
50
- (at_exit { join_hegemon_auto_thread unless $! })
65
+ (flags.include? :in_place) ?
66
+ (@thread.join) :
67
+ (@at_exit = Proc.new { @thread.join if @thread and not $! })
51
68
  end
52
69
 
53
70
  ##
@@ -62,6 +79,20 @@ module Wires
62
79
  block_until_state :dead if (flags.include? :blocking)
63
80
  nil end
64
81
 
82
+ # Register hook to execute before run - can call multiple times
83
+ def before_run(proc=nil, retain:false, &block)
84
+ func = (block or proc)
85
+ expect_type func, Proc
86
+ @before_runs << [func, retain]
87
+ nil end
88
+
89
+ # Register hook to execute after run - can call multiple times
90
+ def after_run(proc=nil, retain:false, &block)
91
+ func = (block or proc)
92
+ expect_type func, Proc
93
+ @after_runs << [func, retain]
94
+ nil end
95
+
65
96
  # Register hook to execute before kill - can call multiple times
66
97
  def before_kill(proc=nil, retain:false, &block)
67
98
  func = (block or proc)
@@ -78,13 +109,17 @@ module Wires
78
109
 
79
110
  # Put x in the queue, and block until x is processed (if Hub is running)
80
111
  def fire(x)
81
- if not dead? # yield to event loop thread until awoken by it later
82
- @queue << [x, Thread.current]
83
- sleep
84
- else # don't wait if Hub isn't running - would cause lockup
85
- @queue << [x, nil]
86
- end
112
+ raise ThreadError, "You can't fire events from this thread." \
113
+ if Thread.current==@_hegemon_auto_thread \
114
+ or Thread.current==@thread
115
+
116
+ @queue << [x, Thread.current]
117
+ (x[2] and @thread) ?
118
+ sleep :
119
+ Thread.pass
120
+
87
121
  nil end
122
+ # threadlock :fire, lock: :@child_threads_lock
88
123
  def <<(x); fire(x); end
89
124
 
90
125
  def flush_queue
@@ -94,7 +129,6 @@ module Wires
94
129
 
95
130
  private
96
131
 
97
-
98
132
  # Flush/run queue of [proc, retain]s, retaining those with retain==true
99
133
  def run_hooks(hooks)
100
134
  retained = Queue.new
@@ -114,9 +148,9 @@ module Wires
114
148
  a_thread = Thread.new{nil}
115
149
  while a_thread
116
150
  @child_threads_lock.synchronize do
151
+ flush_queue
117
152
  a_thread = @child_threads.shift
118
153
  end
119
- flush_queue if alive?
120
154
  a_thread.join if a_thread
121
155
  sleep 0 # Yield to other threads
122
156
  end
@@ -157,7 +191,6 @@ module Wires
157
191
 
158
192
  # Start the new child thread
159
193
  @child_threads << Thread.new do
160
- waiting_thread.wakeup unless blocking or not waiting_thread
161
194
  proc.call(event)
162
195
  waiting_thread.wakeup if blocking and waiting_thread
163
196
  end
@@ -172,6 +205,19 @@ module Wires
172
205
  #***
173
206
  class << self
174
207
  include Hegemon
208
+
209
+ # Protect Hub users methods that could cause deadlock
210
+ # if called from inside an event
211
+ private :state_obj,
212
+ :state_objs,
213
+ :request_state,
214
+ :update_state,
215
+ :do_state_tasks,
216
+ :iter_hegemon_auto_loop,
217
+ :start_hegemon_auto_thread,
218
+ :join_hegemon_auto_thread,
219
+ :end_hegemon_auto_thread
220
+
175
221
  def state_machine_init
176
222
 
177
223
  impose_state :dead
@@ -179,16 +225,25 @@ module Wires
179
225
  declare_state :dead do
180
226
 
181
227
  transition_to :alive do
182
- after { start_hegemon_auto_thread }
228
+ before { run_hooks @before_runs }
229
+ after { run_hooks @after_runs }
230
+ after { do_state_tasks }
231
+ after { start_hegemon_auto_thread(0.1) }
232
+ # after { @fire_proc = @fire_proc_alive }
183
233
  end
184
234
  end
185
235
 
186
236
  declare_state :alive do
187
237
 
188
- task do
189
- # puts "task #{Thread.current.inspect}";
190
- if @queue.empty? then sleep(0)
191
- else process_item(@queue.shift) end
238
+ task do |i|
239
+
240
+ @thread = Thread.new do
241
+ while true
242
+ if @queue.empty? then sleep 0.1
243
+ else process_item(@queue.shift) end
244
+ end
245
+ end if i==0
246
+
192
247
  end
193
248
 
194
249
  transition_to :dead do
@@ -198,11 +253,15 @@ module Wires
198
253
 
199
254
  before { join_children if @please_finish_all }
200
255
 
201
- after { run_hooks @after_kills }
256
+ after { @thread.kill; @thread = nil}
202
257
 
203
258
  after { @please_kill = false }
204
259
  after { @please_finish_all = false }
205
260
 
261
+ after { run_hooks @after_kills }
262
+
263
+ # after { @fire_proc = @fire_proc_dead }
264
+
206
265
  after { end_hegemon_auto_thread }
207
266
  after { do_state_tasks }
208
267
  end
data/lib/wires/time.rb CHANGED
@@ -139,7 +139,6 @@ module Wires
139
139
  def main_loop
140
140
 
141
141
  @keepgoing = true
142
- @thread = Thread.current
143
142
  pending = Array.new
144
143
  on_deck = nil
145
144
 
@@ -172,8 +171,8 @@ module Wires
172
171
 
173
172
  # Use fired event to only start scheduler when Hub is running
174
173
  # This also gets the scheduler loop its own thread within the Hub's threads
175
- on :time_scheduler_start, self do; main_loop; end;
176
- Channel.new(self).fire(:time_scheduler_start)
174
+ # on :time_scheduler_start, self do; main_loop; end;
175
+ # Channel.new(self).fire(:time_scheduler_start)
177
176
 
178
177
  # Stop the main loop upon death of Hub
179
178
  Hub.before_kill(retain:true) do
@@ -183,8 +182,8 @@ module Wires
183
182
  end
184
183
 
185
184
  # Refire the start event after Hub dies in case it restarts
186
- Hub.after_kill(retain:true) do
187
- Channel.new(self).fire(:time_scheduler_start)
185
+ Hub.after_run(retain:true) do
186
+ @thread = Thread.new { main_loop }
188
187
  end
189
188
 
190
189
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wires
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe McIlvain
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-07 00:00:00.000000000 Z
11
+ date: 2013-07-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -24,34 +24,20 @@ dependencies:
24
24
  - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: threadlock
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '>='
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - '>='
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: hegemon
43
29
  requirement: !ruby/object:Gem::Requirement
44
30
  requirements:
45
- - - '>='
31
+ - - ~>
46
32
  - !ruby/object:Gem::Version
47
- version: '0'
33
+ version: 0.0.6
48
34
  type: :runtime
49
35
  prerelease: false
50
36
  version_requirements: !ruby/object:Gem::Requirement
51
37
  requirements:
52
- - - '>='
38
+ - - ~>
53
39
  - !ruby/object:Gem::Version
54
- version: '0'
40
+ version: 0.0.6
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: rake
57
43
  requirement: !ruby/object:Gem::Requirement