Skip to content

Commit 2388793

Browse files
authored
Merge pull request #459 from masamitsu-murase/improve_test_for_multithread
Revive test_busy_handler_outwait and synchronize threads to remove "sleep 1".
2 parents 659d01c + 6899ba3 commit 2388793

File tree

1 file changed

+83
-12
lines changed

1 file changed

+83
-12
lines changed

test/test_integration_pending.rb

+83-12
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,39 @@
33
require "benchmark"
44

55
class IntegrationPendingTestCase < SQLite3::TestCase
6+
class ThreadSynchronizer
7+
def initialize
8+
@main_to_thread = Queue.new
9+
@thread_to_main = Queue.new
10+
end
11+
12+
def send_to_thread state
13+
@main_to_thread.push state
14+
end
15+
16+
def send_to_main state
17+
@thread_to_main.push state
18+
end
19+
20+
def wait_for_thread expected_state
21+
state = @thread_to_main.pop
22+
raise "Invalid state #{state}. #{expected_state} is expected" if state != expected_state
23+
end
24+
25+
def wait_for_main expected_state
26+
state = @main_to_thread.pop
27+
raise "Invalid state #{state}. #{expected_state} is expected" if state != expected_state
28+
end
29+
30+
def close_thread
31+
@thread_to_main.close
32+
end
33+
34+
def close_main
35+
@main_to_thread.close
36+
end
37+
end
38+
639
def setup
740
@db = SQLite3::Database.new("test.db")
841
@db.transaction do
@@ -19,19 +52,20 @@ def teardown
1952
end
2053

2154
def test_busy_handler_impatient
22-
busy = Mutex.new
23-
busy.lock
55+
synchronizer = ThreadSynchronizer.new
2456
handler_call_count = 0
2557

26-
t = Thread.new do
58+
t = Thread.new(synchronizer) do |sync|
2759
db2 = SQLite3::Database.open("test.db")
2860
db2.transaction(:exclusive) do
29-
busy.lock
61+
sync.send_to_main :ready_0
62+
sync.wait_for_main :end_1
3063
end
3164
ensure
3265
db2&.close
66+
sync.close_thread
3367
end
34-
sleep 1
68+
synchronizer.wait_for_thread :ready_0
3569

3670
@db.busy_handler do
3771
handler_call_count += 1
@@ -42,34 +76,37 @@ def test_busy_handler_impatient
4276
@db.execute "insert into foo (b) values ( 'from 2' )"
4377
end
4478

45-
busy.unlock
79+
synchronizer.send_to_thread :end_1
80+
synchronizer.close_main
4681
t.join
4782

4883
assert_equal 1, handler_call_count
4984
end
5085

5186
def test_busy_timeout
5287
@db.busy_timeout 1000
53-
busy = Mutex.new
54-
busy.lock
88+
synchronizer = ThreadSynchronizer.new
5589

56-
t = Thread.new do
90+
t = Thread.new(synchronizer) do |sync|
5791
db2 = SQLite3::Database.open("test.db")
5892
db2.transaction(:exclusive) do
59-
busy.lock
93+
sync.send_to_main :ready_0
94+
sync.wait_for_main :end_1
6095
end
6196
ensure
6297
db2&.close
98+
sync.close_thread
6399
end
64100

65-
sleep 1
101+
synchronizer.wait_for_thread :ready_0
66102
time = Benchmark.measure do
67103
assert_raise(SQLite3::BusyException) do
68104
@db.execute "insert into foo (b) values ( 'from 2' )"
69105
end
70106
end
71107

72-
busy.unlock
108+
synchronizer.send_to_thread :end_1
109+
synchronizer.close_main
73110
t.join
74111

75112
assert_operator time.real * 1000, :>=, 1000
@@ -110,4 +147,38 @@ def test_busy_handler_timeout_releases_gvl
110147

111148
assert_operator work.size - work.find_index("|"), :>, 3
112149
end
150+
151+
def test_busy_handler_outwait
152+
synchronizer = ThreadSynchronizer.new
153+
handler_call_count = 0
154+
155+
t = Thread.new(synchronizer) do |sync|
156+
db2 = SQLite3::Database.open("test.db")
157+
db2.transaction(:exclusive) do
158+
sync.send_to_main :ready_0
159+
sync.wait_for_main :busy_handler_called_1
160+
end
161+
sync.send_to_main :end_of_transaction_2
162+
ensure
163+
db2&.close
164+
sync.close_thread
165+
end
166+
167+
@db.busy_handler do |count|
168+
handler_call_count += 1
169+
synchronizer.send_to_thread :busy_handler_called_1
170+
synchronizer.wait_for_thread :end_of_transaction_2
171+
true
172+
end
173+
174+
synchronizer.wait_for_thread :ready_0
175+
assert_nothing_raised do
176+
@db.execute "insert into foo (b) values ( 'from 2' )"
177+
end
178+
179+
synchronizer.close_main
180+
t.join
181+
182+
assert_equal 1, handler_call_count
183+
end
113184
end

0 commit comments

Comments
 (0)