fsdb 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +6 -0
- data/README.txt +1 -1
- data/lib/fsdb/database.rb +1 -1
- data/rakefile +5 -3
- data/test/test-concurrency.rb +5 -3
- data/test/test-formats.rb +3 -1
- data/test/test-fsdb.rb +5 -3
- metadata +10 -148
- data/junk/OLDRakefile +0 -98
- data/junk/OLDRakefile2 +0 -55
- data/junk/check-cache.rb +0 -18
- data/junk/create-lock.rb +0 -25
- data/junk/doc/old-api/classes/FSDB.html +0 -139
- data/junk/doc/old-api/classes/FSDB/Database.html +0 -953
- data/junk/doc/old-api/classes/FSDB/Database.src/M000029.html +0 -16
- data/junk/doc/old-api/classes/FSDB/Database.src/M000030.html +0 -16
- data/junk/doc/old-api/classes/FSDB/Database.src/M000031.html +0 -16
- data/junk/doc/old-api/classes/FSDB/Database.src/M000032.html +0 -16
- data/junk/doc/old-api/classes/FSDB/Database.src/M000033.html +0 -33
- data/junk/doc/old-api/classes/FSDB/Database.src/M000034.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000035.html +0 -22
- data/junk/doc/old-api/classes/FSDB/Database.src/M000036.html +0 -16
- data/junk/doc/old-api/classes/FSDB/Database.src/M000037.html +0 -22
- data/junk/doc/old-api/classes/FSDB/Database.src/M000038.html +0 -43
- data/junk/doc/old-api/classes/FSDB/Database.src/M000039.html +0 -25
- data/junk/doc/old-api/classes/FSDB/Database.src/M000040.html +0 -43
- data/junk/doc/old-api/classes/FSDB/Database.src/M000041.html +0 -23
- data/junk/doc/old-api/classes/FSDB/Database.src/M000042.html +0 -22
- data/junk/doc/old-api/classes/FSDB/Database.src/M000043.html +0 -16
- data/junk/doc/old-api/classes/FSDB/Database.src/M000044.html +0 -16
- data/junk/doc/old-api/classes/FSDB/Database.src/M000045.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000046.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000047.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000048.html +0 -16
- data/junk/doc/old-api/classes/FSDB/Database.src/M000049.html +0 -71
- data/junk/doc/old-api/classes/FSDB/Database.src/M000050.html +0 -43
- data/junk/doc/old-api/classes/FSDB/Database.src/M000051.html +0 -53
- data/junk/doc/old-api/classes/FSDB/Database.src/M000052.html +0 -44
- data/junk/doc/old-api/classes/FSDB/Database.src/M000053.html +0 -39
- data/junk/doc/old-api/classes/FSDB/Database.src/M000054.html +0 -72
- data/junk/doc/old-api/classes/FSDB/Database.src/M000055.html +0 -39
- data/junk/doc/old-api/classes/FSDB/Database.src/M000056.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000057.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000058.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000059.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000060.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000061.html +0 -23
- data/junk/doc/old-api/classes/FSDB/Database.src/M000062.html +0 -23
- data/junk/doc/old-api/classes/FSDB/Database.src/M000063.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000064.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database/AbortedTransaction.html +0 -118
- data/junk/doc/old-api/classes/FSDB/Database/CreateFileError.html +0 -120
- data/junk/doc/old-api/classes/FSDB/Database/DirIsImmutableError.html +0 -117
- data/junk/doc/old-api/classes/FSDB/Database/DirNotEmptyError.html +0 -117
- data/junk/doc/old-api/classes/FSDB/Database/FormatError.html +0 -117
- data/junk/doc/old-api/classes/FSDB/Database/MissingFileError.html +0 -117
- data/junk/doc/old-api/classes/FSDB/Database/MissingObjectError.html +0 -117
- data/junk/doc/old-api/classes/FSDB/Database/NotDirError.html +0 -118
- data/junk/doc/old-api/classes/FSDB/Database/PathComponentError.html +0 -120
- data/junk/doc/old-api/classes/FSDB/DatabaseDebuggable.html +0 -148
- data/junk/doc/old-api/classes/FSDB/DatabaseDebuggable.src/M000005.html +0 -21
- data/junk/doc/old-api/classes/FSDB/DatabaseDebuggable.src/M000007.html +0 -21
- data/junk/doc/old-api/classes/FSDB/DirectoryIterators.html +0 -210
- data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000006.html +0 -22
- data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000007.html +0 -22
- data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000008.html +0 -22
- data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000009.html +0 -22
- data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000010.html +0 -22
- data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000011.html +0 -22
- data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000012.html +0 -22
- data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000013.html +0 -22
- data/junk/doc/old-api/classes/FSDB/ForkSafely.html +0 -126
- data/junk/doc/old-api/classes/FSDB/Modex.html +0 -237
- data/junk/doc/old-api/classes/FSDB/Modex.src/M000024.html +0 -21
- data/junk/doc/old-api/classes/FSDB/Modex.src/M000025.html +0 -30
- data/junk/doc/old-api/classes/FSDB/Modex.src/M000026.html +0 -21
- data/junk/doc/old-api/classes/FSDB/Modex.src/M000027.html +0 -30
- data/junk/doc/old-api/classes/FSDB/Modex.src/M000028.html +0 -44
- data/junk/doc/old-api/classes/FSDB/Modex.src/M000029.html +0 -26
- data/junk/doc/old-api/classes/FSDB/Modex.src/M000030.html +0 -48
- data/junk/doc/old-api/classes/FSDB/Modex/ForkSafely.html +0 -105
- data/junk/doc/old-api/classes/FSDB/Mutex.html +0 -244
- data/junk/doc/old-api/classes/FSDB/Mutex.src/M000018.html +0 -19
- data/junk/doc/old-api/classes/FSDB/Mutex.src/M000019.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Mutex.src/M000020.html +0 -19
- data/junk/doc/old-api/classes/FSDB/Mutex.src/M000021.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Mutex.src/M000022.html +0 -23
- data/junk/doc/old-api/classes/FSDB/Mutex.src/M000023.html +0 -30
- data/junk/doc/old-api/classes/FSDB/Mutex.src/M000024.html +0 -26
- data/junk/doc/old-api/classes/FSDB/Mutex.src/M000025.html +0 -21
- data/junk/doc/old-api/classes/FSDB/Mutex/ForkSafely.html +0 -105
- data/junk/doc/old-api/classes/FSDB/PathUtilities.html +0 -257
- data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000012.html +0 -23
- data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000013.html +0 -18
- data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000014.html +0 -23
- data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000015.html +0 -18
- data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000016.html +0 -18
- data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000017.html +0 -22
- data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000018.html +0 -23
- data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000019.html +0 -18
- data/junk/doc/old-api/classes/FSDB/PathUtilities/InvalidPathError.html +0 -111
- data/junk/doc/old-api/classes/File.html +0 -272
- data/junk/doc/old-api/classes/File.src/M000001.html +0 -17
- data/junk/doc/old-api/classes/File.src/M000002.html +0 -17
- data/junk/doc/old-api/classes/File.src/M000003.html +0 -20
- data/junk/doc/old-api/classes/File.src/M000004.html +0 -20
- data/junk/doc/old-api/classes/File.src/M000005.html +0 -32
- data/junk/doc/old-api/classes/File.src/M000006.html +0 -32
- data/junk/doc/old-api/created.rid +0 -1
- data/junk/doc/old-api/files/README.html +0 -112
- data/junk/doc/old-api/files/RELEASE-NOTES.html +0 -233
- data/junk/doc/old-api/files/fsdb_txt.html +0 -888
- data/junk/doc/old-api/files/lib/fsdb/database_rb.html +0 -115
- data/junk/doc/old-api/files/lib/fsdb/file-lock_rb.html +0 -109
- data/junk/doc/old-api/files/lib/fsdb/modex_rb.html +0 -121
- data/junk/doc/old-api/files/lib/fsdb/mutex_rb.html +0 -108
- data/junk/doc/old-api/files/lib/fsdb/util_rb.html +0 -108
- data/junk/doc/old-api/fr_class_index.html +0 -47
- data/junk/doc/old-api/fr_file_index.html +0 -34
- data/junk/doc/old-api/fr_method_index.html +0 -90
- data/junk/doc/old-api/index.html +0 -24
- data/junk/doc/old-api/rdoc-style.css +0 -208
- data/junk/file-lock-nb.rb +0 -15
- data/junk/fl.rb +0 -144
- data/junk/flock-test.rb +0 -39
- data/junk/fsdb.kateproject +0 -47
- data/junk/fsdb.prj +0 -196
- data/junk/fsdb.sf +0 -46
- data/junk/insert-dir.rb +0 -48
- data/junk/lock-test-bug.rb +0 -150
- data/junk/lock-test-too-simple.rb +0 -136
- data/junk/lock-test.rb +0 -151
- data/junk/mkrdoc +0 -7
- data/junk/restore-fsdb.rb +0 -37
- data/junk/rf.txt +0 -5
- data/junk/solaris-bug-fixed.rb +0 -184
- data/junk/solaris-bug.rb +0 -182
- data/junk/solaris-bug.txt +0 -43
- data/junk/sync.rb +0 -327
- data/junk/test-file-lock.html +0 -86
- data/junk/test-file-lock.rb +0 -84
- data/junk/test-processes.rb +0 -131
- data/junk/test-threads.rb +0 -113
- data/junk/wiki-mutex.rb +0 -108
- data/misc/fsdb-blorubu.txt +0 -47
- data/misc/mtime-and-file-id.txt +0 -23
- data/misc/posixlock.txt +0 -148
data/junk/test-processes.rb
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
require './test.rb'
|
|
2
|
-
|
|
3
|
-
## should also test nested transactions, replace, insert, delete, etc...
|
|
4
|
-
module TestStressProcesses
|
|
5
|
-
|
|
6
|
-
class ProcessTester
|
|
7
|
-
attr_accessor :x
|
|
8
|
-
def initialize
|
|
9
|
-
@x = 0
|
|
10
|
-
end
|
|
11
|
-
def inspect
|
|
12
|
-
"<ProcessTester:@x=#{@x}>"
|
|
13
|
-
end
|
|
14
|
-
def to_s
|
|
15
|
-
inspect
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def self.go
|
|
20
|
-
|
|
21
|
-
db = $db
|
|
22
|
-
|
|
23
|
-
object_count = 5
|
|
24
|
-
process_count = 10
|
|
25
|
-
rep_count = 1000
|
|
26
|
-
max_sleep = 0.01
|
|
27
|
-
|
|
28
|
-
paths = (0...object_count).map {|i| "thread-test/t#{i}"}
|
|
29
|
-
|
|
30
|
-
paths.each do |path|
|
|
31
|
-
db[path] = ProcessTester.new
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
processes = (0...process_count).map do
|
|
35
|
-
fork do
|
|
36
|
-
srand(Process.pid)
|
|
37
|
-
|
|
38
|
-
rep_count.times do |iter|
|
|
39
|
-
path = paths[rand(paths.size)]
|
|
40
|
-
|
|
41
|
-
case rand(100)
|
|
42
|
-
|
|
43
|
-
when 0..49
|
|
44
|
-
db.browse path do |tester|
|
|
45
|
-
__x__ = tester.x
|
|
46
|
-
|
|
47
|
-
data = File.read(File.join(db.dir, path))
|
|
48
|
-
uncached_x = Marshal.load(data).x
|
|
49
|
-
unless uncached_x == __x__
|
|
50
|
-
fail "browse test: cache is stale:\n" +
|
|
51
|
-
" #{uncached_x} on disk, #{__x__} in cache"
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
sleep(rand*max_sleep)
|
|
55
|
-
|
|
56
|
-
unless __x__ == tester.x
|
|
57
|
-
fail "browse test: x == #{__x__} but tester.x == #{tester.x}"
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
when 50..69
|
|
62
|
-
db.edit path do |tester|
|
|
63
|
-
__x__ = tester.x
|
|
64
|
-
|
|
65
|
-
data = File.read(File.join(db.dir, path))
|
|
66
|
-
uncached_x = Marshal.load(data).x
|
|
67
|
-
unless uncached_x == __x__
|
|
68
|
-
fail "edit test: cache is stale:\n" +
|
|
69
|
-
" #{uncached_x} on disk, #{__x__} in cache"
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
tester.x += 1
|
|
73
|
-
__x__ = tester.x
|
|
74
|
-
|
|
75
|
-
sleep(rand*max_sleep)
|
|
76
|
-
|
|
77
|
-
unless __x__ == tester.x
|
|
78
|
-
fail "edit test: x == #{__x__} but tester.x == #{tester.x}"
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
when 70..90
|
|
83
|
-
db.replace path do |tester|
|
|
84
|
-
__x__ = tester.x
|
|
85
|
-
|
|
86
|
-
data = File.read(File.join(db.dir, path))
|
|
87
|
-
uncached_x = Marshal.load(data).x
|
|
88
|
-
unless uncached_x == __x__
|
|
89
|
-
fail "replace test: cache is stale:\n" +
|
|
90
|
-
" #{uncached_x} on disk, #{__x__} in cache"
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
tester.x += 1
|
|
94
|
-
__x__ = tester.x
|
|
95
|
-
|
|
96
|
-
sleep(rand*max_sleep)
|
|
97
|
-
|
|
98
|
-
unless __x__ == tester.x
|
|
99
|
-
fail "replace test: x == #{__x__} but tester.x == #{tester.x}"
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
tester
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
else
|
|
106
|
-
sleep(rand*max_sleep)
|
|
107
|
-
db.clear_cache
|
|
108
|
-
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
thread = Thread.new do
|
|
116
|
-
i = 0
|
|
117
|
-
loop do
|
|
118
|
-
puts i
|
|
119
|
-
sleep 1
|
|
120
|
-
i += 1
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
process_count.times {Process.wait}
|
|
125
|
-
thread.kill
|
|
126
|
-
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
TestStressProcesses.go if __FILE__ == $0
|
data/junk/test-threads.rb
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
require './test.rb'
|
|
2
|
-
|
|
3
|
-
## should also test nested transactions, replace, insert, delete, etc...
|
|
4
|
-
module TestStressThreads
|
|
5
|
-
|
|
6
|
-
class ThreadTester
|
|
7
|
-
attr_accessor :x
|
|
8
|
-
def initialize
|
|
9
|
-
@x = 0
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def self.go
|
|
14
|
-
|
|
15
|
-
db = $db
|
|
16
|
-
|
|
17
|
-
srand(3765)
|
|
18
|
-
|
|
19
|
-
object_count = 100
|
|
20
|
-
thread_count = 100
|
|
21
|
-
rep_count = 1000
|
|
22
|
-
max_sleep = nil
|
|
23
|
-
|
|
24
|
-
paths = (0...object_count).map {|i| "thread-test/t#{i}"}
|
|
25
|
-
|
|
26
|
-
paths.each do |path|
|
|
27
|
-
db[path] = ThreadTester.new
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
threads = (0...thread_count).map do |thread_index|
|
|
31
|
-
Thread.new(thread_index) do |ti|
|
|
32
|
-
Thread.current[:number] = ti
|
|
33
|
-
Thread.current[:transactions] = 0
|
|
34
|
-
rep_count.times do |iter|
|
|
35
|
-
Thread.current[:iter] = iter
|
|
36
|
-
path = paths[rand(paths.size)]
|
|
37
|
-
|
|
38
|
-
case rand(3)
|
|
39
|
-
|
|
40
|
-
when 0
|
|
41
|
-
db.browse path do |tester|
|
|
42
|
-
__x__ = tester.x
|
|
43
|
-
sleep(rand*max_sleep) if max_sleep
|
|
44
|
-
unless __x__ == tester.x
|
|
45
|
-
fail "browse: x == #{__x__} but tester.x == #{tester.x}"
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
Thread.current[:transactions] += 1
|
|
49
|
-
|
|
50
|
-
when 1
|
|
51
|
-
db.edit path do |tester|
|
|
52
|
-
tester.x += 1
|
|
53
|
-
__x__ = tester.x
|
|
54
|
-
sleep(rand*max_sleep) if max_sleep
|
|
55
|
-
unless __x__ == tester.x
|
|
56
|
-
fail "edit: x == #{__x__} but tester.x == #{tester.x}"
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
Thread.current[:transactions] += 1
|
|
60
|
-
|
|
61
|
-
else
|
|
62
|
-
sleep(rand*max_sleep) if max_sleep
|
|
63
|
-
if rand(20) == 0
|
|
64
|
-
db.clear_cache
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
start_time = Process.times
|
|
74
|
-
|
|
75
|
-
# threads.each{|t|printf "%6d", t[:number]}
|
|
76
|
-
# puts
|
|
77
|
-
# puts "-----|" * threads.size
|
|
78
|
-
sleep 1
|
|
79
|
-
|
|
80
|
-
# stats = old_stats = nil
|
|
81
|
-
loop do
|
|
82
|
-
# old_stats = stats
|
|
83
|
-
# stats = threads.map{|t|t[:iter]}
|
|
84
|
-
# stats.each{|s|printf "%6d", s}
|
|
85
|
-
puts "."
|
|
86
|
-
break unless threads.any?{|t|t.alive?}
|
|
87
|
-
# if old_stats == stats
|
|
88
|
-
# fail "Deadlock!"
|
|
89
|
-
# end
|
|
90
|
-
sleep 1
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
end_time = Process.times
|
|
94
|
-
|
|
95
|
-
utime = end_time.utime - start_time.utime
|
|
96
|
-
stime = end_time.stime - start_time.stime
|
|
97
|
-
rate = threads.inject(0) {|sum, t| sum += t[:transactions]} /
|
|
98
|
-
(utime + stime)
|
|
99
|
-
|
|
100
|
-
puts "All db worker threads dead."
|
|
101
|
-
puts "time: %12s%12s" % %w{user system}
|
|
102
|
-
puts " %12.2f%12.2f" % [utime, stime]
|
|
103
|
-
puts "\nExecuted %d transactions per second" % rate
|
|
104
|
-
|
|
105
|
-
threads.each do |thread|
|
|
106
|
-
thread.join
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
TestStressThreads.go
|
data/junk/wiki-mutex.rb
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
|
|
3
|
-
require 'thread'
|
|
4
|
-
|
|
5
|
-
# Mutex class based on standard thread.rb Mutex, which has some problems:
|
|
6
|
-
# - waiters are not a strict queue (try_lock can jump the queue, after
|
|
7
|
-
# which the queue gets *rotated*). Race condition.
|
|
8
|
-
# - doesn't use Thread.exclusive in enough places
|
|
9
|
-
# - no way to make dead threads give up the mutex, which is crucial in a fork
|
|
10
|
-
class ForkableMutex
|
|
11
|
-
def initialize
|
|
12
|
-
@waiting = [] # queue of waiting threads
|
|
13
|
-
@locked = nil; # the thread that has the lock
|
|
14
|
-
@waiting.taint # enable tainted comunication
|
|
15
|
-
self.taint
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def locked?
|
|
19
|
-
@locked
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def try_lock
|
|
23
|
-
Thread.exclusive do
|
|
24
|
-
if not @locked and @waiting.empty?
|
|
25
|
-
@locked = Thread.current
|
|
26
|
-
true
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def lock
|
|
32
|
-
thread = Thread.current
|
|
33
|
-
Thread.exclusive do
|
|
34
|
-
if @locked
|
|
35
|
-
@waiting.push thread
|
|
36
|
-
Thread.stop
|
|
37
|
-
unless @locked == thread
|
|
38
|
-
raise ThreadError, "queue was jumped"
|
|
39
|
-
end
|
|
40
|
-
else
|
|
41
|
-
@locked = thread
|
|
42
|
-
end
|
|
43
|
-
self
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def unlock
|
|
48
|
-
return unless @locked
|
|
49
|
-
|
|
50
|
-
t = Thread.exclusive { wake_next_waiter }
|
|
51
|
-
|
|
52
|
-
begin
|
|
53
|
-
t.run if t
|
|
54
|
-
rescue ThreadError
|
|
55
|
-
end
|
|
56
|
-
self
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def synchronize
|
|
60
|
-
lock
|
|
61
|
-
yield
|
|
62
|
-
ensure
|
|
63
|
-
unlock
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def remove_dead
|
|
67
|
-
Thread.exclusive do
|
|
68
|
-
@waiting = @waiting.select {|t| t.alive?}
|
|
69
|
-
wake_next_waiter if @locked and not @locked.alive?
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
private
|
|
74
|
-
def wake_next_waiter
|
|
75
|
-
t = @waiting.shift
|
|
76
|
-
t.wakeup if t
|
|
77
|
-
@locked = t
|
|
78
|
-
rescue ThreadError
|
|
79
|
-
retry
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
module ForkSafely
|
|
84
|
-
def fork
|
|
85
|
-
super do
|
|
86
|
-
ObjectSpace.each_object(ForkableMutex) { |m| m.remove_dead }
|
|
87
|
-
yield
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
include ForkSafely
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if __FILE__ == $0
|
|
95
|
-
include ForkSafely
|
|
96
|
-
|
|
97
|
-
m = ForkableMutex.new
|
|
98
|
-
|
|
99
|
-
Thread.new { m.synchronize { sleep 2 } }
|
|
100
|
-
|
|
101
|
-
fork do
|
|
102
|
-
m.synchronize { puts "Didn't get here if you used standard mutex or fork." }
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
m.synchronize { puts "Got here." }
|
|
106
|
-
|
|
107
|
-
Process.wait
|
|
108
|
-
end
|
data/misc/fsdb-blorubu.txt
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
Like pstore, fsdb is:
|
|
2
|
-
|
|
3
|
-
- pure ruby, cross-platform
|
|
4
|
-
|
|
5
|
-
- ruby license
|
|
6
|
-
|
|
7
|
-
- simple API
|
|
8
|
-
|
|
9
|
-
- simple implementation (though less so)
|
|
10
|
-
|
|
11
|
-
- transaction based, with abort capability
|
|
12
|
-
|
|
13
|
-
However, pstore has some drawbacks:
|
|
14
|
-
|
|
15
|
-
- not thread-safe (though it is process-safe)
|
|
16
|
-
|
|
17
|
-
- coarse granularity (transaction applies to whole pstore), does not scale well
|
|
18
|
-
|
|
19
|
-
- uses marshalling, even if your data is is some other format that doesn't require the overhead of marshalling (e.g., strings, binary data)
|
|
20
|
-
|
|
21
|
-
Other advantages of fsdb:
|
|
22
|
-
|
|
23
|
-
- can use YAML (or other formats) where you want to (e.g., in user settings, but perhaps not for large ruby objects or binary data). It's easy to specify a mapping from path patterns to data formats.
|
|
24
|
-
|
|
25
|
-
- thread-safe, so you can easily wire it up to a multithreaded server, like drb (see examples/server.rb)
|
|
26
|
-
|
|
27
|
-
- objects in the database are just files, and so can be manipulated with standard command line tools (including rsync, versioning tools, etc.).
|
|
28
|
-
|
|
29
|
-
- granularity is up to you: you can have lots of little objects, if you want, (there are tradeoffs, of course)
|
|
30
|
-
|
|
31
|
-
- scales as well as the fs does
|
|
32
|
-
|
|
33
|
-
- thoroughly stress-tested, partially unit-tested. (But still not quite stable on Windows.)
|
|
34
|
-
|
|
35
|
-
- Can select fcntl-based locking (if platform supports it), which should allow safe use with NFS mounts on linux
|
|
36
|
-
|
|
37
|
-
Disadvantages of fsdb:
|
|
38
|
-
|
|
39
|
-
- If you want indexes, you need to implement them on top of fsdb. You could do:
|
|
40
|
-
|
|
41
|
-
db['name-index'] = RBTree.new
|
|
42
|
-
|
|
43
|
-
and define your own methods for adding/removing objects that also updates the name-index. The name-index maps names (or other keys) to paths in the db.
|
|
44
|
-
|
|
45
|
-
- Likewise, no SQL, out of the box.
|
|
46
|
-
|
|
47
|
-
- Efficiency and reliability depends on the fs. (My benchmarks get on the order of 1000 transactions per sec on a 3 yr old linux box.)
|
data/misc/mtime-and-file-id.txt
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
mtime granularity on win?
|
|
2
|
-
|
|
3
|
-
see:
|
|
4
|
-
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/by_handle_file_information_str.asp
|
|
5
|
-
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/file_times.asp
|
|
6
|
-
|
|
7
|
-
http://www.google.com/search?hl=en&ie=ISO-8859-1&q=unique+file+id+on+windows&btnG=Google+Search
|
|
8
|
-
|
|
9
|
-
http://discuss.fogcreek.com/joelonsoftware/default.asp?cmd=show&ixPost=42340
|
|
10
|
-
|
|
11
|
-
Windows can give a unique file indentifier using the function GetFileInformationByHandle() (See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/getfileinformationbyhandle.asp)
|
|
12
|
-
|
|
13
|
-
Example: (hFile is a handle to a file)
|
|
14
|
-
|
|
15
|
-
BY_HANDLE_FILE_INFORMATION FileInfo;
|
|
16
|
-
|
|
17
|
-
GetFileInformationByHandle(hFile, &FileInfo);
|
|
18
|
-
inode= FileInfo.nFileIndexLow | (FileInfo.nFileIndexHigh << 32);
|
|
19
|
-
volume=FileInfo.dwVolumeSerialNumber;
|
|
20
|
-
|
|
21
|
-
According to Micorsoft : "The identifier (low and high parts) and the volume serial number uniquely identify a file on a single computer. To determine whether two open handles represent the same file, combine this identifier and the volume serial number for each file and compare them."
|
|
22
|
-
|
|
23
|
-
|
data/misc/posixlock.txt
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
Subject:
|
|
2
|
-
[ANN] posixlock
|
|
3
|
-
From:
|
|
4
|
-
"Ara.T.Howard" <ahoward@ngdc.noaa.gov>
|
|
5
|
-
Date:
|
|
6
|
-
Sat, 6 Dec 2003 05:22:07 +0900
|
|
7
|
-
To:
|
|
8
|
-
ruby-talk@ruby-lang.org (ruby-talk ML)
|
|
9
|
-
Newsgroups:
|
|
10
|
-
comp.lang.ruby
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
SYNOPSIS:
|
|
14
|
-
posixlock
|
|
15
|
-
use fcntl (vs. flock) based locking for File#flock
|
|
16
|
-
|
|
17
|
-
USAGE
|
|
18
|
-
require 'posixlock' # replaces File#flock!
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
i currently do not have a place to post software - so here's a little
|
|
22
|
-
extension that replaces flock with an fcntl based impl for posix compliant
|
|
23
|
-
locking (safe on nfs) - posted to c.l.r for posterity:
|
|
24
|
-
|
|
25
|
-
extconf.rb
|
|
26
|
-
================
|
|
27
|
-
require 'mkmf'
|
|
28
|
-
create_makefile 'posixlock'
|
|
29
|
-
================
|
|
30
|
-
|
|
31
|
-
posixlock.c
|
|
32
|
-
================
|
|
33
|
-
#ifdef _WIN32
|
|
34
|
-
#include "missing/file.h"
|
|
35
|
-
#endif
|
|
36
|
-
|
|
37
|
-
#include "ruby.h"
|
|
38
|
-
#include "rubyio.h"
|
|
39
|
-
#include "rubysig.h"
|
|
40
|
-
|
|
41
|
-
#ifdef HAVE_UNISTD_H
|
|
42
|
-
#include <unistd.h>
|
|
43
|
-
#endif
|
|
44
|
-
|
|
45
|
-
#ifdef HAVE_FCNTL_H
|
|
46
|
-
#include <fcntl.h>
|
|
47
|
-
#endif
|
|
48
|
-
|
|
49
|
-
#include <errno.h>
|
|
50
|
-
|
|
51
|
-
extern VALUE rb_cFile;
|
|
52
|
-
|
|
53
|
-
# ifndef LOCK_SH
|
|
54
|
-
# define LOCK_SH 1
|
|
55
|
-
# endif
|
|
56
|
-
# ifndef LOCK_EX
|
|
57
|
-
# define LOCK_EX 2
|
|
58
|
-
# endif
|
|
59
|
-
# ifndef LOCK_NB
|
|
60
|
-
# define LOCK_NB 4
|
|
61
|
-
# endif
|
|
62
|
-
# ifndef LOCK_UN
|
|
63
|
-
# define LOCK_UN 8
|
|
64
|
-
# endif
|
|
65
|
-
|
|
66
|
-
static int
|
|
67
|
-
posixlock (fd, operation)
|
|
68
|
-
int fd;
|
|
69
|
-
int operation;
|
|
70
|
-
{
|
|
71
|
-
struct flock lock;
|
|
72
|
-
|
|
73
|
-
switch (operation & ~LOCK_NB)
|
|
74
|
-
{
|
|
75
|
-
case LOCK_SH:
|
|
76
|
-
lock.l_type = F_RDLCK;
|
|
77
|
-
break;
|
|
78
|
-
case LOCK_EX:
|
|
79
|
-
lock.l_type = F_WRLCK;
|
|
80
|
-
break;
|
|
81
|
-
case LOCK_UN:
|
|
82
|
-
lock.l_type = F_UNLCK;
|
|
83
|
-
break;
|
|
84
|
-
default:
|
|
85
|
-
errno = EINVAL;
|
|
86
|
-
return -1;
|
|
87
|
-
}
|
|
88
|
-
lock.l_whence = SEEK_SET;
|
|
89
|
-
lock.l_start = lock.l_len = 0L;
|
|
90
|
-
return fcntl (fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &lock);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
static VALUE
|
|
95
|
-
rb_file_posixlock (obj, operation)
|
|
96
|
-
VALUE obj;
|
|
97
|
-
VALUE operation;
|
|
98
|
-
{
|
|
99
|
-
#ifndef __CHECKER__
|
|
100
|
-
OpenFile *fptr;
|
|
101
|
-
int ret;
|
|
102
|
-
|
|
103
|
-
rb_secure (2);
|
|
104
|
-
GetOpenFile (obj, fptr);
|
|
105
|
-
|
|
106
|
-
if (fptr->mode & FMODE_WRITABLE)
|
|
107
|
-
{
|
|
108
|
-
fflush (GetWriteFile (fptr));
|
|
109
|
-
}
|
|
110
|
-
retry:
|
|
111
|
-
TRAP_BEG;
|
|
112
|
-
ret = posixlock (fileno (fptr->f), NUM2INT (operation));
|
|
113
|
-
TRAP_END;
|
|
114
|
-
if (ret < 0)
|
|
115
|
-
{
|
|
116
|
-
switch (errno)
|
|
117
|
-
{
|
|
118
|
-
case EAGAIN:
|
|
119
|
-
case EACCES:
|
|
120
|
-
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
|
|
121
|
-
case EWOULDBLOCK:
|
|
122
|
-
#endif
|
|
123
|
-
return Qfalse;
|
|
124
|
-
case EINTR:
|
|
125
|
-
#if defined(ERESTART)
|
|
126
|
-
case ERESTART:
|
|
127
|
-
#endif
|
|
128
|
-
goto retry;
|
|
129
|
-
}
|
|
130
|
-
rb_sys_fail (fptr->path);
|
|
131
|
-
}
|
|
132
|
-
#endif
|
|
133
|
-
|
|
134
|
-
return INT2FIX (0);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
void
|
|
139
|
-
Init_posixlock()
|
|
140
|
-
{
|
|
141
|
-
rb_define_method(rb_cFile, "flock", rb_file_posixlock, 1);
|
|
142
|
-
}
|
|
143
|
-
================
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
-a
|
|
148
|
-
-- ATTN: please update your address books with address below! =============================================================================== | EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov | PHONE :: 303.497.6469 | ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328 | STP :: http://www.ngdc.noaa.gov/stp/ | NGDC :: http://www.ngdc.noaa.gov/ | NESDIS :: http://www.nesdis.noaa.gov/ | NOAA :: http://www.noaa.gov/ | US DOC :: http://www.commerce.gov/ | | The difference between art and science is that science is what we | understand well enough to explain to a computer. | Art is everything else. | -- Donald Knuth, "Discover" | | /bin/sh -c 'for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done' ===============================================================================
|