fsdb 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. data/History.txt +6 -0
  2. data/README.txt +1 -1
  3. data/lib/fsdb/database.rb +1 -1
  4. data/rakefile +5 -3
  5. data/test/test-concurrency.rb +5 -3
  6. data/test/test-formats.rb +3 -1
  7. data/test/test-fsdb.rb +5 -3
  8. metadata +10 -148
  9. data/junk/OLDRakefile +0 -98
  10. data/junk/OLDRakefile2 +0 -55
  11. data/junk/check-cache.rb +0 -18
  12. data/junk/create-lock.rb +0 -25
  13. data/junk/doc/old-api/classes/FSDB.html +0 -139
  14. data/junk/doc/old-api/classes/FSDB/Database.html +0 -953
  15. data/junk/doc/old-api/classes/FSDB/Database.src/M000029.html +0 -16
  16. data/junk/doc/old-api/classes/FSDB/Database.src/M000030.html +0 -16
  17. data/junk/doc/old-api/classes/FSDB/Database.src/M000031.html +0 -16
  18. data/junk/doc/old-api/classes/FSDB/Database.src/M000032.html +0 -16
  19. data/junk/doc/old-api/classes/FSDB/Database.src/M000033.html +0 -33
  20. data/junk/doc/old-api/classes/FSDB/Database.src/M000034.html +0 -18
  21. data/junk/doc/old-api/classes/FSDB/Database.src/M000035.html +0 -22
  22. data/junk/doc/old-api/classes/FSDB/Database.src/M000036.html +0 -16
  23. data/junk/doc/old-api/classes/FSDB/Database.src/M000037.html +0 -22
  24. data/junk/doc/old-api/classes/FSDB/Database.src/M000038.html +0 -43
  25. data/junk/doc/old-api/classes/FSDB/Database.src/M000039.html +0 -25
  26. data/junk/doc/old-api/classes/FSDB/Database.src/M000040.html +0 -43
  27. data/junk/doc/old-api/classes/FSDB/Database.src/M000041.html +0 -23
  28. data/junk/doc/old-api/classes/FSDB/Database.src/M000042.html +0 -22
  29. data/junk/doc/old-api/classes/FSDB/Database.src/M000043.html +0 -16
  30. data/junk/doc/old-api/classes/FSDB/Database.src/M000044.html +0 -16
  31. data/junk/doc/old-api/classes/FSDB/Database.src/M000045.html +0 -18
  32. data/junk/doc/old-api/classes/FSDB/Database.src/M000046.html +0 -18
  33. data/junk/doc/old-api/classes/FSDB/Database.src/M000047.html +0 -18
  34. data/junk/doc/old-api/classes/FSDB/Database.src/M000048.html +0 -16
  35. data/junk/doc/old-api/classes/FSDB/Database.src/M000049.html +0 -71
  36. data/junk/doc/old-api/classes/FSDB/Database.src/M000050.html +0 -43
  37. data/junk/doc/old-api/classes/FSDB/Database.src/M000051.html +0 -53
  38. data/junk/doc/old-api/classes/FSDB/Database.src/M000052.html +0 -44
  39. data/junk/doc/old-api/classes/FSDB/Database.src/M000053.html +0 -39
  40. data/junk/doc/old-api/classes/FSDB/Database.src/M000054.html +0 -72
  41. data/junk/doc/old-api/classes/FSDB/Database.src/M000055.html +0 -39
  42. data/junk/doc/old-api/classes/FSDB/Database.src/M000056.html +0 -18
  43. data/junk/doc/old-api/classes/FSDB/Database.src/M000057.html +0 -18
  44. data/junk/doc/old-api/classes/FSDB/Database.src/M000058.html +0 -18
  45. data/junk/doc/old-api/classes/FSDB/Database.src/M000059.html +0 -18
  46. data/junk/doc/old-api/classes/FSDB/Database.src/M000060.html +0 -18
  47. data/junk/doc/old-api/classes/FSDB/Database.src/M000061.html +0 -23
  48. data/junk/doc/old-api/classes/FSDB/Database.src/M000062.html +0 -23
  49. data/junk/doc/old-api/classes/FSDB/Database.src/M000063.html +0 -18
  50. data/junk/doc/old-api/classes/FSDB/Database.src/M000064.html +0 -18
  51. data/junk/doc/old-api/classes/FSDB/Database/AbortedTransaction.html +0 -118
  52. data/junk/doc/old-api/classes/FSDB/Database/CreateFileError.html +0 -120
  53. data/junk/doc/old-api/classes/FSDB/Database/DirIsImmutableError.html +0 -117
  54. data/junk/doc/old-api/classes/FSDB/Database/DirNotEmptyError.html +0 -117
  55. data/junk/doc/old-api/classes/FSDB/Database/FormatError.html +0 -117
  56. data/junk/doc/old-api/classes/FSDB/Database/MissingFileError.html +0 -117
  57. data/junk/doc/old-api/classes/FSDB/Database/MissingObjectError.html +0 -117
  58. data/junk/doc/old-api/classes/FSDB/Database/NotDirError.html +0 -118
  59. data/junk/doc/old-api/classes/FSDB/Database/PathComponentError.html +0 -120
  60. data/junk/doc/old-api/classes/FSDB/DatabaseDebuggable.html +0 -148
  61. data/junk/doc/old-api/classes/FSDB/DatabaseDebuggable.src/M000005.html +0 -21
  62. data/junk/doc/old-api/classes/FSDB/DatabaseDebuggable.src/M000007.html +0 -21
  63. data/junk/doc/old-api/classes/FSDB/DirectoryIterators.html +0 -210
  64. data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000006.html +0 -22
  65. data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000007.html +0 -22
  66. data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000008.html +0 -22
  67. data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000009.html +0 -22
  68. data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000010.html +0 -22
  69. data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000011.html +0 -22
  70. data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000012.html +0 -22
  71. data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000013.html +0 -22
  72. data/junk/doc/old-api/classes/FSDB/ForkSafely.html +0 -126
  73. data/junk/doc/old-api/classes/FSDB/Modex.html +0 -237
  74. data/junk/doc/old-api/classes/FSDB/Modex.src/M000024.html +0 -21
  75. data/junk/doc/old-api/classes/FSDB/Modex.src/M000025.html +0 -30
  76. data/junk/doc/old-api/classes/FSDB/Modex.src/M000026.html +0 -21
  77. data/junk/doc/old-api/classes/FSDB/Modex.src/M000027.html +0 -30
  78. data/junk/doc/old-api/classes/FSDB/Modex.src/M000028.html +0 -44
  79. data/junk/doc/old-api/classes/FSDB/Modex.src/M000029.html +0 -26
  80. data/junk/doc/old-api/classes/FSDB/Modex.src/M000030.html +0 -48
  81. data/junk/doc/old-api/classes/FSDB/Modex/ForkSafely.html +0 -105
  82. data/junk/doc/old-api/classes/FSDB/Mutex.html +0 -244
  83. data/junk/doc/old-api/classes/FSDB/Mutex.src/M000018.html +0 -19
  84. data/junk/doc/old-api/classes/FSDB/Mutex.src/M000019.html +0 -18
  85. data/junk/doc/old-api/classes/FSDB/Mutex.src/M000020.html +0 -19
  86. data/junk/doc/old-api/classes/FSDB/Mutex.src/M000021.html +0 -18
  87. data/junk/doc/old-api/classes/FSDB/Mutex.src/M000022.html +0 -23
  88. data/junk/doc/old-api/classes/FSDB/Mutex.src/M000023.html +0 -30
  89. data/junk/doc/old-api/classes/FSDB/Mutex.src/M000024.html +0 -26
  90. data/junk/doc/old-api/classes/FSDB/Mutex.src/M000025.html +0 -21
  91. data/junk/doc/old-api/classes/FSDB/Mutex/ForkSafely.html +0 -105
  92. data/junk/doc/old-api/classes/FSDB/PathUtilities.html +0 -257
  93. data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000012.html +0 -23
  94. data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000013.html +0 -18
  95. data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000014.html +0 -23
  96. data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000015.html +0 -18
  97. data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000016.html +0 -18
  98. data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000017.html +0 -22
  99. data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000018.html +0 -23
  100. data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000019.html +0 -18
  101. data/junk/doc/old-api/classes/FSDB/PathUtilities/InvalidPathError.html +0 -111
  102. data/junk/doc/old-api/classes/File.html +0 -272
  103. data/junk/doc/old-api/classes/File.src/M000001.html +0 -17
  104. data/junk/doc/old-api/classes/File.src/M000002.html +0 -17
  105. data/junk/doc/old-api/classes/File.src/M000003.html +0 -20
  106. data/junk/doc/old-api/classes/File.src/M000004.html +0 -20
  107. data/junk/doc/old-api/classes/File.src/M000005.html +0 -32
  108. data/junk/doc/old-api/classes/File.src/M000006.html +0 -32
  109. data/junk/doc/old-api/created.rid +0 -1
  110. data/junk/doc/old-api/files/README.html +0 -112
  111. data/junk/doc/old-api/files/RELEASE-NOTES.html +0 -233
  112. data/junk/doc/old-api/files/fsdb_txt.html +0 -888
  113. data/junk/doc/old-api/files/lib/fsdb/database_rb.html +0 -115
  114. data/junk/doc/old-api/files/lib/fsdb/file-lock_rb.html +0 -109
  115. data/junk/doc/old-api/files/lib/fsdb/modex_rb.html +0 -121
  116. data/junk/doc/old-api/files/lib/fsdb/mutex_rb.html +0 -108
  117. data/junk/doc/old-api/files/lib/fsdb/util_rb.html +0 -108
  118. data/junk/doc/old-api/fr_class_index.html +0 -47
  119. data/junk/doc/old-api/fr_file_index.html +0 -34
  120. data/junk/doc/old-api/fr_method_index.html +0 -90
  121. data/junk/doc/old-api/index.html +0 -24
  122. data/junk/doc/old-api/rdoc-style.css +0 -208
  123. data/junk/file-lock-nb.rb +0 -15
  124. data/junk/fl.rb +0 -144
  125. data/junk/flock-test.rb +0 -39
  126. data/junk/fsdb.kateproject +0 -47
  127. data/junk/fsdb.prj +0 -196
  128. data/junk/fsdb.sf +0 -46
  129. data/junk/insert-dir.rb +0 -48
  130. data/junk/lock-test-bug.rb +0 -150
  131. data/junk/lock-test-too-simple.rb +0 -136
  132. data/junk/lock-test.rb +0 -151
  133. data/junk/mkrdoc +0 -7
  134. data/junk/restore-fsdb.rb +0 -37
  135. data/junk/rf.txt +0 -5
  136. data/junk/solaris-bug-fixed.rb +0 -184
  137. data/junk/solaris-bug.rb +0 -182
  138. data/junk/solaris-bug.txt +0 -43
  139. data/junk/sync.rb +0 -327
  140. data/junk/test-file-lock.html +0 -86
  141. data/junk/test-file-lock.rb +0 -84
  142. data/junk/test-processes.rb +0 -131
  143. data/junk/test-threads.rb +0 -113
  144. data/junk/wiki-mutex.rb +0 -108
  145. data/misc/fsdb-blorubu.txt +0 -47
  146. data/misc/mtime-and-file-id.txt +0 -23
  147. data/misc/posixlock.txt +0 -148
data/junk/sync.rb DELETED
@@ -1,327 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- unless defined? Thread.exclusive
4
- def Thread.exclusive
5
- old = Thread.critical
6
- begin
7
- Thread.critical = true
8
- return yield
9
- ensure
10
- Thread.critical = old
11
- end
12
- end
13
- end
14
-
15
- module FSDB
16
-
17
- # Synchronzer class based on standard sync.rb, which has some problems:
18
- # - waiters are not a strict queue (try_lock can jump the queue, after
19
- # which the queue gets *rotated*). Race condition.
20
- # - doesn't use Thread.exclusive in enough places
21
- # - no way to make dead threads give up the mutex, which is crucial in a fork
22
-
23
- # based on standard sync.rb
24
- module Sync_m
25
- # lock mode
26
- UN = :UN
27
- SH = :SH
28
- EX = :EX
29
-
30
- # exceptions
31
- class Err < StandardError
32
- def Err.Fail(*opt)
33
- fail self, sprintf(self::Message, *opt)
34
- end
35
-
36
- class UnknownLocker < Err
37
- Message = "Thread(%s) not locked."
38
- def UnknownLocker.Fail(th)
39
- super(th.inspect)
40
- end
41
- end
42
-
43
- class LockModeFailer < Err
44
- Message = "Unknown lock mode(%s)"
45
- def LockModeFailer.Fail(mode)
46
- if mode.id2name
47
- mode = id2name
48
- end
49
- super(mode)
50
- end
51
- end
52
- end
53
-
54
- def Sync_m.define_aliases(cl)
55
- cl.module_eval %q{
56
- alias locked? sync_locked?
57
- alias shared? sync_shared?
58
- alias exclusive? sync_exclusive?
59
- alias lock sync_lock
60
- alias unlock sync_unlock
61
- alias try_lock sync_try_lock
62
- alias synchronize sync_synchronize
63
- }
64
- end
65
-
66
- def Sync_m.append_features(cl)
67
- super
68
- unless cl.instance_of?(Module)
69
- # do nothing for Modules
70
- # make aliases and include the proper module.
71
- define_aliases(cl)
72
- end
73
- end
74
-
75
- def Sync_m.extend_object(obj)
76
- super
77
- obj.sync_extended
78
- end
79
-
80
- def sync_extended
81
- unless (defined? locked? and
82
- defined? shared? and
83
- defined? exclusive? and
84
- defined? lock and
85
- defined? unlock and
86
- defined? try_lock and
87
- defined? synchronize)
88
- Sync_m.define_aliases(class<<self;self;end)
89
- end
90
- sync_initialize
91
- end
92
-
93
- # accessing
94
- def sync_locked?
95
- sync_mode != UN
96
- end
97
-
98
- def sync_shared?
99
- sync_mode == SH
100
- end
101
-
102
- def sync_exclusive?
103
- sync_mode == EX
104
- end
105
-
106
- # locking methods.
107
- def sync_try_lock(mode = EX)
108
- return unlock if sync_mode == UN
109
-
110
- Thread.critical = true
111
- ret = sync_try_lock_sub(sync_mode)
112
- Thread.critical = false
113
- ret
114
- end
115
-
116
- def sync_lock(m = EX)
117
- return unlock if m == UN
118
-
119
- until (Thread.critical = true; sync_try_lock_sub(m))
120
- if sync_sh_locker[Thread.current]
121
- sync_upgrade_waiting.push [Thread.current, sync_sh_locker[Thread.current]]
122
- sync_sh_locker.delete(Thread.current)
123
- else
124
- sync_waiting.push Thread.current
125
- end
126
- Thread.stop
127
- end
128
- Thread.critical = false
129
- self
130
- end
131
-
132
- def sync_unlock(m = EX)
133
- Thread.critical = true
134
- if sync_mode == UN
135
- Thread.critical = false
136
- Err::UnknownLocker.Fail(Thread.current)
137
- end
138
-
139
- m = sync_mode if m == EX and sync_mode == SH
140
-
141
- runnable = false
142
- case m
143
- when UN
144
- Thread.critical = false
145
- Err::UnknownLocker.Fail(Thread.current)
146
-
147
- when EX
148
- if sync_ex_locker == Thread.current
149
- if (self.sync_ex_count = sync_ex_count - 1) == 0
150
- self.sync_ex_locker = nil
151
- if sync_sh_locker.include?(Thread.current)
152
- self.sync_mode = SH
153
- else
154
- self.sync_mode = UN
155
- end
156
- runnable = true
157
- end
158
- else
159
- Err::UnknownLocker.Fail(Thread.current)
160
- end
161
-
162
- when SH
163
- if (count = sync_sh_locker[Thread.current]).nil?
164
- Err::UnknownLocker.Fail(Thread.current)
165
- else
166
- if (sync_sh_locker[Thread.current] = count - 1) == 0
167
- sync_sh_locker.delete(Thread.current)
168
- if sync_sh_locker.empty? and sync_ex_count == 0
169
- self.sync_mode = UN
170
- runnable = true
171
- end
172
- end
173
- end
174
- end
175
-
176
- if runnable
177
- if sync_upgrade_waiting.size > 0
178
- for k, v in sync_upgrade_waiting
179
- sync_sh_locker[k] = v
180
- end
181
- wait = sync_upgrade_waiting
182
- self.sync_upgrade_waiting = []
183
- Thread.critical = false
184
-
185
- for w, v in wait
186
- w.run
187
- end
188
- else
189
- wait = sync_waiting
190
- self.sync_waiting = []
191
- Thread.critical = false
192
- for w in wait
193
- w.run
194
- end
195
- end
196
- end
197
-
198
- Thread.critical = false
199
- self
200
- end
201
-
202
- def sync_synchronize(mode = EX)
203
- begin
204
- sync_lock(mode)
205
- yield
206
- ensure
207
- sync_unlock
208
- end
209
- end
210
-
211
- attr :sync_mode, true
212
-
213
- attr :sync_waiting, true
214
- attr :sync_upgrade_waiting, true
215
- attr :sync_sh_locker, true
216
- attr :sync_ex_locker, true
217
- attr :sync_ex_count, true
218
-
219
- private
220
-
221
- def sync_initialize
222
- @sync_mode = UN
223
- @sync_waiting = []
224
- @sync_upgrade_waiting = []
225
- @sync_sh_locker = Hash.new
226
- @sync_ex_locker = nil
227
- @sync_ex_count = 0
228
- end
229
-
230
- def initialize(*args)
231
- sync_initialize
232
- super
233
- end
234
-
235
- def sync_try_lock_sub(m)
236
- case m
237
- when SH
238
- case sync_mode
239
- when UN
240
- self.sync_mode = m
241
- sync_sh_locker[Thread.current] = 1
242
- ret = true
243
- when SH
244
- count = 0 unless count = sync_sh_locker[Thread.current]
245
- sync_sh_locker[Thread.current] = count + 1
246
- ret = true
247
- when EX
248
- # in EX mode, lock will upgrade to EX lock
249
- if sync_ex_locker == Thread.current
250
- self.sync_ex_count = sync_ex_count + 1
251
- ret = true
252
- else
253
- ret = false
254
- end
255
- end
256
- when EX
257
- if sync_mode == UN or
258
- sync_mode == SH && sync_sh_locker.size == 1 && sync_sh_locker.include?(Thread.current)
259
- self.sync_mode = m
260
- self.sync_ex_locker = Thread.current
261
- self.sync_ex_count = 1
262
- ret = true
263
- elsif sync_mode == EX && sync_ex_locker == Thread.current
264
- self.sync_ex_count = sync_ex_count + 1
265
- ret = true
266
- else
267
- ret = false
268
- end
269
- else
270
- Thread.critical = false
271
- Err::LockModeFailer.Fail mode
272
- end
273
- return ret
274
- end
275
- end
276
- Synchronizer_m = Sync_m
277
-
278
- class Sync
279
- #Sync_m.extend_class self
280
- include Sync_m
281
-
282
- def initialize
283
- super
284
- end
285
-
286
- module ForkSafely
287
- def fork
288
- super do
289
- ### ObjectSpace.each_object(Sync) { |m| m.remove_dead_waiters }
290
- yield
291
- end
292
- end
293
- end
294
- end
295
- Synchronizer = Sync
296
-
297
-
298
- # FSDB users who fork should include ForkSafely or FSDB itself, or they
299
- # should make sure to call FSDB.fork instead of Kernel.fork. If you use
300
- # mutexes (outside of those in FSDB), they should be FSDB::Mutexes.
301
- module ForkSafely
302
- include Sync::ForkSafely
303
- end
304
- include ForkSafely
305
-
306
- end # module FSDB
307
-
308
-
309
- if __FILE__ == $0
310
- include FSDB::ForkSafely
311
-
312
- m = FSDB::Synchronizer.new
313
-
314
- EX = FSDB::Synchronizer::EX
315
-
316
- Thread.new { m.synchronize(EX) { sleep 1 } }
317
-
318
- fork do
319
- m.synchronize(EX) {
320
- puts "Didn't get here if you used standard sync or fork."
321
- }
322
- end
323
-
324
- m.synchronize(EX) { puts "Got here." }
325
-
326
- Process.wait
327
- end
@@ -1,86 +0,0 @@
1
- <?xml version="1.0" ?>
2
- <!DOCTYPE html
3
- PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
- <html xmlns="http://www.w3.org/1999/xhtml">
6
- <head>
7
- <title>Untitled</title>
8
- </head>
9
- <body>
10
- <p>require 'thread' # for exclusive
11
- require 'fsdb/file-lock'
12
- require 'fsdb/modex.rb'; Sync = FSDB::Modex</p>
13
- <p>include File::OpenLock</p>
14
- <p>process_count = 2
15
- thread_count = 2
16
- rep_count = (ARGV.shift || 10000).to_i
17
- modex = Sync.new</p>
18
- <p>test_file = '/tmp/test-file-lock.dat' ## also try NFS</p>
19
- <p>File.open(test_file, "w") {|f| Marshal.dump(0, f)}</p>
20
- <p>(0...process_count).each do</p>
21
- <pre>fork do
22
-
23
- increments = 0
24
-
25
- threads =
26
- (0...thread_count).map do
27
- Thread.new do
28
- (0...rep_count).each do
29
- if rand(100) &lt; 50
30
- modex.synchronize(Sync::SH) do
31
- open_read_lock(test_file) do |f|
32
- str = f.read
33
- data = Marshal.load(str)
34
- end
35
- end
36
- else
37
- modex.synchronize(Sync::EX) do
38
- open_write_lock(test_file) do |f|
39
- str = f.read
40
- data = Marshal.load(str)
41
- data += 1
42
- f.rewind; f.truncate(0)
43
- Marshal.dump(data, f)
44
- f.flush
45
- Thread.exclusive {increments += 1}
46
- end
47
- end
48
- end
49
- end
50
- end
51
- end
52
-
53
- threads.each {|thread| thread.join}
54
-
55
- File.open("#{test_file}#{Process.pid}", "w") do |f|
56
- Marshal.dump(increments, f)
57
- end
58
-
59
- end</pre>
60
- <p>end</p>
61
- <p>Thread.new do</p>
62
- <pre>count = 0
63
- loop do
64
- puts count
65
- sleep 1
66
- count += 1
67
- end </pre>
68
- <p>end</p>
69
- <p>increments = 0
70
- (0...process_count).each do</p>
71
- <pre>pid = Process.wait
72
- File.open("#{test_file}#{pid}", "r") do |f|
73
- increments += Marshal.load(f)
74
- end</pre>
75
- <p>end</p>
76
- <p>data = File.open(test_file, "r") {|f| Marshal.load(f)}</p>
77
- <p>if data == increments</p>
78
- <pre>puts "Equal counts: #{data}"</pre>
79
- <p>else</p>
80
- <pre>puts "Not equal:"
81
- puts " increments: #{increments}"
82
- puts " data : #{data}"</pre>
83
- <p>end</p>
84
-
85
- </body>
86
- </html>
@@ -1,84 +0,0 @@
1
- require 'thread' # for exclusive
2
- require 'fsdb/file-lock'
3
- require 'fsdb/modex.rb'; Sync = FSDB::Modex
4
- #require 'sync'
5
-
6
- include File::OpenLock
7
-
8
- process_count = 2
9
- thread_count = 2
10
- rep_count = (ARGV.shift || 10000).to_i
11
- modex = Sync.new
12
-
13
- test_file = '/tmp/test-file-lock.dat' ## also try NFS
14
-
15
- File.open(test_file, "w") {|f| Marshal.dump(0, f)}
16
-
17
- (0...process_count).each do
18
- fork do
19
-
20
- increments = 0
21
-
22
- threads =
23
- (0...thread_count).map do
24
- Thread.new do
25
- (0...rep_count).each do
26
- if rand(100) < 50
27
- modex.synchronize(Sync::SH) do
28
- open_read_lock(test_file) do |f|
29
- str = f.read
30
- data = Marshal.load(str)
31
- end
32
- end
33
- else
34
- modex.synchronize(Sync::EX) do
35
- open_write_lock(test_file) do |f|
36
- str = f.read
37
- data = Marshal.load(str)
38
- data += 1
39
- f.rewind; f.truncate(0)
40
- Marshal.dump(data, f)
41
- f.flush
42
- Thread.exclusive {increments += 1}
43
- end
44
- end
45
- end
46
- end
47
- end
48
- end
49
-
50
- threads.each {|thread| thread.join}
51
-
52
- File.open("#{test_file}#{Process.pid}", "w") do |f|
53
- Marshal.dump(increments, f)
54
- end
55
-
56
- end
57
- end
58
-
59
- Thread.new do
60
- count = 0
61
- loop do
62
- puts count
63
- sleep 1
64
- count += 1
65
- end
66
- end
67
-
68
- increments = 0
69
- (0...process_count).each do
70
- pid = Process.wait
71
- File.open("#{test_file}#{pid}", "r") do |f|
72
- increments += Marshal.load(f)
73
- end
74
- end
75
-
76
- data = File.open(test_file, "r") {|f| Marshal.load(f)}
77
-
78
- if data == increments
79
- puts "Equal counts: #{data}"
80
- else
81
- puts "Not equal:"
82
- puts " increments: #{increments}"
83
- puts " data : #{data}"
84
- end