wires 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
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