blob: a1ad8760c9d2cf39e3b5d10eface4a4aa4d96c24 (
plain)
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
# See the file LICENSE for redistribution information.
#
# Copyright (c) 1996-2002
# Sleepycat Software. All rights reserved.
#
# $Id: lock002.tcl,v 11.19 2002/04/25 19:30:29 sue Exp $
#
# TEST lock002
# TEST Exercise basic multi-process aspects of lock.
proc lock002 { {maxlocks 1000} {conflicts {0 0 0 0 0 1 0 1 1} } } {
source ./include.tcl
puts "Lock002: Basic multi-process lock tests."
env_cleanup $testdir
set nmodes [isqrt [llength $conflicts]]
# Open the lock
mlock_open $maxlocks $nmodes $conflicts
mlock_wait
}
# Make sure that we can create a region; destroy it, attach to it,
# detach from it, etc.
proc mlock_open { maxl nmodes conflicts } {
source ./include.tcl
global lock_curid
global lock_maxid
puts "\tLock002.a multi-process open/close test"
# Open/Create region here. Then close it and try to open from
# other test process.
set env_cmd [concat "berkdb_env -create -mode 0644 \
-lock -lock_max $maxl -lock_conflict" \
[list [list $nmodes $conflicts]] "-home $testdir"]
set local_env [eval $env_cmd]
$local_env lock_id_set $lock_curid $lock_maxid
error_check_good env_open [is_valid_env $local_env] TRUE
set ret [$local_env close]
error_check_good env_close $ret 0
# Open from other test process
set env_cmd "berkdb_env -mode 0644 -home $testdir"
set f1 [open |$tclsh_path r+]
puts $f1 "source $test_path/test.tcl"
set remote_env [send_cmd $f1 $env_cmd]
error_check_good remote:env_open [is_valid_env $remote_env] TRUE
# Now make sure that we can reopen the region.
set local_env [eval $env_cmd]
error_check_good env_open [is_valid_env $local_env] TRUE
set ret [$local_env close]
error_check_good env_close $ret 0
# Try closing the remote region
set ret [send_cmd $f1 "$remote_env close"]
error_check_good remote:lock_close $ret 0
# Try opening for create. Will succeed because region exists.
set env_cmd [concat "berkdb_env -create -mode 0644 \
-lock -lock_max $maxl -lock_conflict" \
[list [list $nmodes $conflicts]] "-home $testdir"]
set local_env [eval $env_cmd]
error_check_good remote:env_open [is_valid_env $local_env] TRUE
# close locally
reset_env $local_env
# Close and exit remote
set ret [send_cmd $f1 "reset_env $remote_env"]
catch { close $f1 } result
}
proc mlock_wait { } {
source ./include.tcl
puts "\tLock002.b multi-process get/put wait test"
# Open region locally
set env_cmd "berkdb_env -lock -home $testdir"
set local_env [eval $env_cmd]
error_check_good env_open [is_valid_env $local_env] TRUE
# Open region remotely
set f1 [open |$tclsh_path r+]
puts $f1 "source $test_path/test.tcl"
set remote_env [send_cmd $f1 $env_cmd]
error_check_good remote:env_open [is_valid_env $remote_env] TRUE
# Get a write lock locally; try for the read lock
# remotely. We hold the locks for several seconds
# so that we can use timestamps to figure out if the
# other process waited.
set locker1 [$local_env lock_id]
set local_lock [$local_env lock_get write $locker1 object1]
error_check_good lock_get [is_valid_lock $local_lock $local_env] TRUE
# Now request a lock that we expect to hang; generate
# timestamps so we can tell if it actually hangs.
set locker2 [send_cmd $f1 "$remote_env lock_id"]
set remote_lock [send_timed_cmd $f1 1 \
"set lock \[$remote_env lock_get write $locker2 object1\]"]
# Now sleep before releasing lock
tclsleep 5
set result [$local_lock put]
error_check_good lock_put $result 0
# Now get the result from the other script
set result [rcv_result $f1]
error_check_good lock_get:remote_time [expr $result > 4] 1
# Now get the remote lock
set remote_lock [send_cmd $f1 "puts \$lock"]
error_check_good remote:lock_get \
[is_valid_lock $remote_lock $remote_env] TRUE
# Now make the other guy wait 5 second and then release his
# lock while we try to get a write lock on it
set start [timestamp -r]
set ret [send_cmd $f1 "tclsleep 5"]
set ret [send_cmd $f1 "$remote_lock put"]
set local_lock [$local_env lock_get write $locker1 object1]
error_check_good lock_get:time \
[expr [expr [timestamp -r] - $start] > 2] 1
error_check_good lock_get:local \
[is_valid_lock $local_lock $local_env] TRUE
# Now check remote's result
set result [rcv_result $f1]
error_check_good lock_put:remote $result 0
# Clean up remote
set result [send_cmd $f1 "$remote_env lock_id_free $locker2" ]
error_check_good remote_free_id $result 0
set ret [send_cmd $f1 "reset_env $remote_env"]
close $f1
# Now close up locally
set ret [$local_lock put]
error_check_good lock_put $ret 0
error_check_good lock_id_free [$local_env lock_id_free $locker1] 0
reset_env $local_env
}
|