Skip to content

Commit 4420411

Browse files
authored
Merge pull request #30 from miry/single-thread-reactor-op-count
fix: Make sure the variable op_count is initialized
2 parents 417e627 + 58247ca commit 4420411

File tree

1 file changed

+14
-11
lines changed

1 file changed

+14
-11
lines changed

lib/crystalruby/reactor.rb

Lines changed: 14 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
@@ -108,8 +110,8 @@ def start!
108110
@op_count += 1
109111
invoke_gc_if_due!(lib)
110112
end
111-
rescue StopReactor => e
112-
rescue StandardError => e
113+
rescue StopReactor
114+
rescue => e
113115
CrystalRuby.log_error "Error: #{e}"
114116
CrystalRuby.log_error e.backtrace
115117
end
@@ -123,20 +125,21 @@ def gc_due?
123125
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
124126

125127
# Initialize state variables if not already set.
126-
@last_gc_time ||= now
127-
@last_gc_op_count ||= @op_count
128+
@last_gc_time ||= now
129+
@op_count ||= 0
130+
@last_gc_op_count ||= @op_count
128131
@last_mem_check_time ||= now
129132

130133
# Calculate differences based on ops and time.
131-
ops_since_last_gc = @op_count - @last_gc_op_count
134+
ops_since_last_gc = @op_count - @last_gc_op_count
132135
time_since_last_gc = now - @last_gc_time
133136

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

137140
if due
138141
# Update the baseline values after GC is scheduled.
139-
@last_gc_time = now
142+
@last_gc_time = now
140143
# If we just did a memory check, use that value; otherwise, fetch one now.
141144
@last_gc_op_count = @op_count
142145
Types::Allocator.gc_hint_reset!
@@ -173,10 +176,10 @@ def invoke_blocking!(receiver, op_name, *args, tvars, _lib)
173176
tvars[:error] = nil
174177
begin
175178
tvars[:result] = receiver.send(op_name, *args)
176-
rescue StopReactor => e
179+
rescue StopReactor
177180
tvars[:cond].signal
178181
raise
179-
rescue StandardError => e
182+
rescue => e
180183
tvars[:error] = e
181184
end
182185
tvars[:cond].signal
@@ -191,8 +194,8 @@ def schedule_work!(receiver, op_name, *args, return_type, blocking: true, async:
191194
if @single_thread_mode || (Thread.current.object_id == @main_thread_id && op_name != :yield)
192195
unless Thread.current.object_id == @main_thread_id
193196
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}"
197+
"Single thread mode is enabled, cannot run in multi-threaded mode. " \
198+
"Reactor was started from: #{@main_thread_id}, then called from #{Thread.current.object_id}"
196199
end
197200
invoke_gc_if_due!(lib)
198201
return receiver.send(op_name, *args)

0 commit comments

Comments
 (0)