1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
-- this script tests the fix of a bug that could cause the mutex of a keeper state to remain locked
-- see https://github.com/LuaLanes/lanes/commit/0cc1c9c9dcea5955f7dab921d9a2fff78c4e1729
local lanes = require "lanes"
-- Lua 5.1 compatibility
local table_unpack = table.unpack or unpack
local SLEEP = function(...)
local k, v = lanes.sleep(...)
assert(k == nil and v == "timeout")
end
print "let's begin"
local do_extra_stuff = true
if do_extra_stuff then
local linda = lanes.linda "deadlock_linda"
-- just something to make send() succeed and receive() fail
local payload = { io.flush }
-- lane generator. don't initialize "io" base library so that it is not known in the lane
local g = lanes.gen('base,table', function()
lane_threadname( "deadlock_lane")
-- wrapping inside pcall makes the Lanes module unaware that something went wrong
print( "In lane 1:", table_unpack{ pcall( linda.receive, linda, 'tmp')})
-- with the bug not fixed, and non-recursive mutexes, we can hang here
print( "In lane 2:", table_unpack{ pcall( linda.receive, linda, 'tmp')})
-- return something out of the lane
return 33, 55
end)
-- send payload twice. succeeds because sending stores a function identification string in the linda's keeper state
linda:send( 'tmp', payload, payload)
-- start the lane
local h = g()
-- wait for lane completion
local err, stack = h:join()
print( 'result of lane execution', err, stack)
end
-- With the bug not fixed, the linda keeper's mutex is still acquired,
-- and the program hangs when the internal linda used for timers attempts to acquire the same keeper (there is only one by default)
print('waiting a bit')
SLEEP(2)
print('we should reach here')
|