ruined 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/ChangeLog +5 -1
  2. data/lib/ruined/ruinmain.rb +81 -39
  3. metadata +4 -4
data/ChangeLog CHANGED
@@ -1,4 +1,8 @@
1
- Tue Oct 13 21:01:00 2010 arton
1
+ Wed Oct 13 22:39:00 2010 arton
2
+ * ruined/ruinmain.rb
3
+ version 0.0.5 => 0.0.6
4
+ support multi-thread app (but very limited)
5
+ Wed Oct 13 21:01:00 2010 arton
2
6
  * Rakefile
3
7
  add BSDL into gem
4
8
  * ruined/html/main.html
@@ -9,14 +9,51 @@ require 'monitor'
9
9
  require 'stringio'
10
10
 
11
11
  module Ruined
12
- RUINED_VERSION = '0.0.5'
12
+ RUINED_VERSION = '0.0.6'
13
13
 
14
14
  @queue = [Queue.new, Queue.new]
15
15
  @breakpoints = []
16
16
  @monitor = Monitor.new
17
- @tlses = { '$!' => nil, '$?' => nil, '$@' => nil, '$SAFE' => nil}
18
17
  IGNORES = [:$&, :$', :$+, :$_, :$`, :$~, :$KCODE, :$= ]
18
+ @unbreakable_threads = []
19
19
 
20
+ class <<Thread
21
+ alias :_original_start :start
22
+ def start(&proc)
23
+ webrick = caller.first.include?('webrick')
24
+ $stderr.puts "caller=#{caller[2]}, webrick=#{webrick}"
25
+ $stderr.flush
26
+ _original_start do
27
+ Ruined.add_unbreakable(Thread.current) if webrick
28
+ begin
29
+ proc.call
30
+ ensure
31
+ Ruined.remove_unbreakable(Thread.current) if webrick
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ class Context
38
+ TLSES = ['$!', '$?', '$@', '$SAFE']
39
+ def initialize(e, f, l, id, bnd, b, s)
40
+ @event = e
41
+ @file = f
42
+ @line = l
43
+ @iid = id.to_s
44
+ @break = b
45
+ @binding = bnd
46
+ @stdout = s
47
+ @tlses = Hash[*(TLSES.map{|k| [k, eval(k)]}.flatten(1))]
48
+ end
49
+ def to_hash
50
+ { :event => @event, :file => @file, :line => @line, :id => @iid, :break => @break,
51
+ :stdout => @stdout }
52
+ end
53
+ attr_reader :tlses, :file, :line, :iid, :binding, :break
54
+ attr_accessor :event, :stdout
55
+ end
56
+
20
57
  include WEBrick
21
58
  svr = HTTPServer.new(:Port => 8383,
22
59
  :ServerType => Thread,
@@ -70,13 +107,13 @@ module Ruined
70
107
 
71
108
  def stepping(*a)
72
109
  Ruined.wait 1
73
- JSON(Ruined.current)
110
+ JSON(Ruined.current_context)
74
111
  end
75
112
 
76
113
  def cont(*a)
77
114
  Ruined.release 0
78
115
  Ruined.wait 1
79
- JSON(Ruined.current)
116
+ JSON(Ruined.current_context)
80
117
  end
81
118
 
82
119
  def step(*a)
@@ -145,8 +182,8 @@ module Ruined
145
182
  end
146
183
  end
147
184
 
148
- def self.current
149
- @current
185
+ def self.current_context
186
+ @current.to_hash
150
187
  end
151
188
 
152
189
  def self.breakpoints
@@ -159,7 +196,7 @@ local_variables.map do |_0|
159
196
  (_0 == :_) ? nil : { :name => _0.to_s, :value => eval(_0.to_s) }
160
197
  end - [nil]
161
198
  EOD
162
- @current_binding ? eval(script, @current_binding) : []
199
+ @current.binding ? eval(script, @current.binding) : []
163
200
  end
164
201
 
165
202
  def self.self_vars
@@ -172,7 +209,7 @@ self.class.class_variables.map do |v|
172
209
  { :name => v.to_s, :value => instance_eval(v.to_s) }
173
210
  end
174
211
  EOD
175
- @current_binding ? eval(script, @current_binding) : []
212
+ @current.binding ? eval(script, @current.binding) : []
176
213
  end
177
214
 
178
215
  def self.global_vars
@@ -187,38 +224,30 @@ end - [nil]
187
224
  EOD
188
225
  a = eval(script)
189
226
  0.upto(a.size - 1) do |i|
190
- if @tlses.has_key?(a[i][:name])
191
- a[i][:value] = @tlses[a[i][:name]]
227
+ if @current.tlses.has_key?(a[i][:name])
228
+ a[i][:value] = @current.tlses[a[i][:name]]
192
229
  end
193
230
  end
194
231
  a
195
232
  end
196
233
 
197
234
  def self.set(var, val)
198
- eval("#{var} = #{val}", @current_binding)
235
+ eval("#{var} = #{val}", @current.binding)
199
236
  end
200
237
 
201
- def self.tls_vars
202
- @@tlses
203
- end
204
-
205
238
  def self.wait(t)
206
- @monitor.synchronize {
207
- unless @queue[t].empty?
208
- @queue[t].clear
209
- logger.debug("------------not wait exit #{t}")
210
- return
211
- end
212
- }
213
239
  logger.debug("------------wait #{t}")
214
- @queue[t].pop
240
+ o = @queue[t].pop
241
+ if t == 1
242
+ @current = o
243
+ end
215
244
  logger.debug("------------wait exit #{t}")
216
245
  end
217
246
 
218
- def self.release(t)
247
+ def self.release(t, obj = nil)
219
248
  logger.debug("------------release #{t}")
220
249
  @monitor.synchronize {
221
- @queue[t].push nil
250
+ @queue[t].push obj
222
251
  }
223
252
  logger.debug("------------release exit #{t}")
224
253
  end
@@ -234,6 +263,24 @@ EOD
234
263
  end
235
264
  ret
236
265
  end
266
+
267
+ def self.add_unbreakable(t)
268
+ @monitor.synchronize {
269
+ @unbreakable_threads << t
270
+ }
271
+ end
272
+
273
+ def self.remove_unbreakable(t)
274
+ @monitor.synchronize {
275
+ @unbreakable_threads.delete t
276
+ }
277
+ end
278
+
279
+ def self.unbreakable?(t)
280
+ @monitor.synchronize {
281
+ @unbreakable_threads.include? t
282
+ }
283
+ end
237
284
 
238
285
  svr.mount('/debug', DebugServlet)
239
286
  svr.mount_proc('/quit') do |req, res|
@@ -264,23 +311,18 @@ EOD
264
311
 
265
312
  svr.start
266
313
 
267
- main_thread = Thread.current
268
-
269
314
  set_trace_func Proc.new {|event, file, line, id, binding, klass|
270
- unless file =~ %r#(lib/ruby|webrick|internal)# || main_thread != Thread.current
315
+ unless file =~ %r#(lib/ruby|ruinmain|webrick|internal)# || unbreakable?(Thread.current)
271
316
  if event.index('c-') != 0
272
317
  if file == $0 && !$stdout.instance_of?(StringIO)
273
318
  $stdout = StringIO.new
274
319
  end
275
- @tlses.each do |k, v|
276
- @tlses[k] = eval(k)
277
- end
278
320
  b = breakpoints.include? [file, line]
279
- @current_binding = binding
280
- @current = { 'event' => event, 'file' => file, 'line' => line,
281
- 'id' => id.to_s, 'break' => b, 'stdout' => output }
282
- svr.logger.debug(@current.inspect)
283
- release 1
321
+ ctxt = @monitor.synchronize {
322
+ Context.new(event, file, line, id, binding, b, output)
323
+ }
324
+ svr.logger.debug(ctxt.inspect)
325
+ release 1, ctxt
284
326
  wait 0
285
327
  svr.logger.debug('continue...')
286
328
  end
@@ -288,9 +330,9 @@ EOD
288
330
  }
289
331
  at_exit {
290
332
  if @current
291
- @current['event'] = 'exit'
292
- @current['stdout'] = output
293
- release 1
333
+ @current.event = 'exit'
334
+ @current.stdout = output
335
+ release 1, @current #reschedule
294
336
  wait 0
295
337
  end
296
338
  }
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruined
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 5
10
- version: 0.0.5
9
+ - 6
10
+ version: 0.0.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - arton
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-13 00:00:00 +09:00
18
+ date: 2010-10-14 00:00:00 +09:00
19
19
  default_executable:
20
20
  dependencies: []
21
21