Skip to content

Commit 0bb7edf

Browse files
committed
fix: Make sure the class variable op_count is initialized
When run Reactor in the single thread mode, skips the Initialization of the @op_count. ``` NoMethodError: undefined method '-' for nil lib/crystalruby/reactor.rb:133:in 'CrystalRuby::Reactor.gc_due?' lib/crystalruby/reactor.rb:121:in 'CrystalRuby::Reactor.invoke_gc_if_due!' lib/crystalruby/reactor.rb:199:in 'CrystalRuby::Reactor.schedule_work!' lib/crystalruby/function.rb:73:in 'block (2 levels) in TestTime#define_crystallized_methods!' test/types/test_time.rb:30:in 'TestTime#test_it_can_do_time_math'` ```
1 parent 417e627 commit 0bb7edf

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

lib/crystalruby/reactor.rb

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ module Reactor
1010
module_function
1111

1212
class SingleThreadViolation < StandardError; end
13+
1314
class StopReactor < StandardError; end
1415

16+
@op_count = 0
1517
@single_thread_mode = false
1618

1719
REACTOR_QUEUE = Queue.new
@@ -44,7 +46,7 @@ class StopReactor < StandardError; end
4446

4547
# We memoize callbacks, once per return type
4648
CALLBACKS_MAP = Hash.new do |h, rt|
47-
h[rt] = FFI::Function.new(:void, [:int, *(rt == :void ? [] : [rt])]) do |tid, ret|
49+
h[rt] = FFI::Function.new(:void, [:int, *((rt == :void) ? [] : [rt])]) do |tid, ret|
4850
THREAD_MAP[tid][:error] = nil
4951
THREAD_MAP[tid][:result] = ret
5052
THREAD_MAP[tid][:cond].signal
@@ -104,12 +106,13 @@ def start!
104106
CrystalRuby.log_debug("CrystalRuby initialized")
105107
while true
106108
handler, *args, lib = REACTOR_QUEUE.pop
109+
puts "\n\n\n======================="
107110
send(handler, *args, lib)
108111
@op_count += 1
109112
invoke_gc_if_due!(lib)
110113
end
111-
rescue StopReactor => e
112-
rescue StandardError => e
114+
rescue StopReactor
115+
rescue => e
113116
CrystalRuby.log_error "Error: #{e}"
114117
CrystalRuby.log_error e.backtrace
115118
end
@@ -123,20 +126,21 @@ def gc_due?
123126
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
124127

125128
# Initialize state variables if not already set.
126-
@last_gc_time ||= now
127-
@last_gc_op_count ||= @op_count
129+
@last_gc_time ||= now
130+
@op_count ||= 0
131+
@last_gc_op_count ||= @op_count
128132
@last_mem_check_time ||= now
129133

130134
# Calculate differences based on ops and time.
131-
ops_since_last_gc = @op_count - @last_gc_op_count
135+
ops_since_last_gc = @op_count - @last_gc_op_count
132136
time_since_last_gc = now - @last_gc_time
133137

134138
# Start with our two “cheap” conditions.
135139
due = (ops_since_last_gc >= GC_OP_THRESHOLD) || (time_since_last_gc >= GC_INTERVAL) || Types::Allocator.gc_bytes_seen > GC_BYTES_SEEN_THRESHOLD
136140

137141
if due
138142
# Update the baseline values after GC is scheduled.
139-
@last_gc_time = now
143+
@last_gc_time = now
140144
# If we just did a memory check, use that value; otherwise, fetch one now.
141145
@last_gc_op_count = @op_count
142146
Types::Allocator.gc_hint_reset!
@@ -173,10 +177,10 @@ def invoke_blocking!(receiver, op_name, *args, tvars, _lib)
173177
tvars[:error] = nil
174178
begin
175179
tvars[:result] = receiver.send(op_name, *args)
176-
rescue StopReactor => e
180+
rescue StopReactor
177181
tvars[:cond].signal
178182
raise
179-
rescue StandardError => e
183+
rescue => e
180184
tvars[:error] = e
181185
end
182186
tvars[:cond].signal
@@ -191,8 +195,8 @@ def schedule_work!(receiver, op_name, *args, return_type, blocking: true, async:
191195
if @single_thread_mode || (Thread.current.object_id == @main_thread_id && op_name != :yield)
192196
unless Thread.current.object_id == @main_thread_id
193197
raise SingleThreadViolation,
194-
"Single thread mode is enabled, cannot run in multi-threaded mode. " \
195-
"Reactor was started from: #{@main_thread_id}, then called from #{Thread.current.object_id}"
198+
"Single thread mode is enabled, cannot run in multi-threaded mode. " \
199+
"Reactor was started from: #{@main_thread_id}, then called from #{Thread.current.object_id}"
196200
end
197201
invoke_gc_if_due!(lib)
198202
return receiver.send(op_name, *args)

0 commit comments

Comments
 (0)