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
@@ -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
@@ -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.)
@@ -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' ===============================================================================