fsdb 0.6.1 → 0.7.0

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.
@@ -1,138 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- ### only use this if you can ensure Thread.critical is not already set!
4
- ### it mught be worth implementing a granular atomic-add-based mutex in
5
- ### place of Thread.critical
6
-
7
- # Make sure we use the fast definition, not the thread.rb one!
8
- class Thread # :nodoc:
9
- def self.exclusive
10
- old = critical
11
- self.critical = true
12
- yield
13
- ensure
14
- self.critical = old
15
- end
16
- end
17
-
18
- module FSDB
19
-
20
- # Mutex class based on standard thread.rb Mutex, which has some problems:
21
- #
22
- # - waiters are not a strict queue (try_lock can jump the queue, after
23
- # which the queue gets *rotated*). Race condition.
24
- #
25
- # - doesn't use Thread.exclusive in enough places
26
- #
27
- # - no way to make dead threads give up the mutex, which is crucial in a fork
28
- #
29
- # Note: neither this Mutex nor the one in thread.rb is nestable.
30
- #
31
- class Mutex
32
- def initialize
33
- @waiting = []
34
- @locked = nil
35
- end
36
-
37
- def locked?
38
- @locked
39
- end
40
-
41
- def try_lock
42
- Thread.critical = true
43
- if not @locked
44
- @locked = Thread.current
45
- rslt = true
46
- end
47
- Thread.critical = false
48
- rslt
49
- end
50
-
51
- def lock
52
- thread = Thread.current
53
- Thread.critical = true
54
- if @locked
55
- @waiting.push thread
56
- Thread.stop
57
- unless @locked == thread
58
- raise ThreadError, "queue was jumped"
59
- end
60
- else
61
- @locked = thread
62
- end
63
- Thread.critical = false
64
- self
65
- end
66
-
67
- def unlock
68
- return unless @locked
69
-
70
- Thread.critical = true; t = wake_next_waiter; Thread.critical = false
71
-
72
- begin
73
- t.run if t
74
- rescue ThreadError
75
- end
76
- self
77
- end
78
-
79
- def synchronize
80
- lock
81
- yield
82
- ensure
83
- unlock
84
- end
85
-
86
- def remove_dead # :nodoc:
87
- Thread.critical = true
88
- @waiting = @waiting.select {|t| t.alive?}
89
- wake_next_waiter if @locked and not @locked.alive?
90
- Thread.critical = false
91
- end
92
-
93
- private
94
- def wake_next_waiter
95
- t = @waiting.shift
96
- t.wakeup if t
97
- @locked = t
98
- rescue ThreadError
99
- retry
100
- end
101
-
102
- module ForkSafely
103
- def fork # :nodoc:
104
- super do
105
- ObjectSpace.each_object(Mutex) { |m| m.remove_dead }
106
- yield
107
- end
108
- end
109
- end
110
- end
111
-
112
- # FSDB users who fork should include ForkSafely or FSDB itself. If you use
113
- # mutexes (outside of those in FSDB), they should be FSDB::Mutexes.
114
- module ForkSafely
115
- include Mutex::ForkSafely
116
- end
117
- include ForkSafely
118
-
119
- end # module FSDB
120
-
121
-
122
- if __FILE__ == $0
123
- # Stress test is in fsdb/test/test-mutex.rb. This is just to show fork usage.
124
-
125
- include FSDB::ForkSafely
126
-
127
- m = FSDB::Mutex.new
128
-
129
- Thread.new { m.synchronize { sleep 1 } }
130
-
131
- fork do
132
- m.synchronize { puts "Didn't get here if you used standard mutex or fork." }
133
- end
134
-
135
- m.synchronize { puts "Got here." }
136
-
137
- Process.wait
138
- end
@@ -1,137 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- unless defined? Thread.exclusive
4
- class Thread # :nodoc:
5
- def self.exclusive
6
- old = critical
7
- self.critical = true
8
- yield
9
- ensure
10
- self.critical = old
11
- end
12
- end
13
- end
14
-
15
- module FSDB
16
-
17
- # Mutex class based on standard thread.rb Mutex, which has some problems:
18
- #
19
- # - waiters are not a strict queue (try_lock can jump the queue, after
20
- # which the queue gets *rotated*). Race condition.
21
- #
22
- # - doesn't use Thread.exclusive in enough places
23
- #
24
- # - no way to make dead threads give up the mutex, which is crucial in a fork
25
- #
26
- # Note: neither this Mutex nor the one in thread.rb is nestable.
27
- #
28
- class Mutex
29
- def initialize
30
- @waiting = []
31
- @locked = nil
32
- @waiting.taint # enable tainted comunication
33
- self.taint
34
- end
35
-
36
- def locked?
37
- @locked
38
- end
39
-
40
- def try_lock
41
- Thread.exclusive do
42
- if not @locked # and @waiting.empty? # not needed
43
- @locked = Thread.current
44
- true
45
- end
46
- end
47
- end
48
-
49
- def lock
50
- thread = Thread.current
51
- Thread.exclusive do
52
- if @locked
53
- @waiting.push thread
54
- Thread.stop
55
- unless @locked == thread
56
- raise ThreadError, "queue was jumped"
57
- end
58
- else
59
- @locked = thread
60
- end
61
- self
62
- end
63
- end
64
-
65
- def unlock
66
- return unless @locked
67
-
68
- t = Thread.exclusive { wake_next_waiter }
69
-
70
- begin
71
- t.run if t
72
- rescue ThreadError
73
- end
74
- self
75
- end
76
-
77
- def synchronize
78
- lock
79
- yield
80
- ensure
81
- unlock
82
- end
83
-
84
- def remove_dead # :nodoc:
85
- Thread.exclusive do
86
- @waiting = @waiting.select {|t| t.alive?}
87
- wake_next_waiter if @locked and not @locked.alive?
88
- ## what if @locked thread left the resource in an inconsistent state?
89
- end
90
- end
91
-
92
- private
93
- def wake_next_waiter
94
- t = @waiting.shift
95
- t.wakeup if t
96
- @locked = t
97
- rescue ThreadError
98
- retry
99
- end
100
-
101
- module ForkSafely
102
- def fork # :nodoc:
103
- super do
104
- ObjectSpace.each_object(Mutex) { |m| m.remove_dead }
105
- yield
106
- end
107
- end
108
- end
109
- end
110
-
111
- # FSDB users who fork should include ForkSafely or FSDB itself. If you use
112
- # mutexes (outside of those in FSDB), they should be FSDB::Mutexes.
113
- module ForkSafely
114
- include Mutex::ForkSafely
115
- end
116
- include ForkSafely
117
-
118
- end # module FSDB
119
-
120
-
121
- if __FILE__ == $0
122
- # Stress test is in fsdb/test/test-mutex.rb. This is just to show fork usage.
123
-
124
- include FSDB::ForkSafely
125
-
126
- m = FSDB::Mutex.new
127
-
128
- Thread.new { m.synchronize { sleep 1 } }
129
-
130
- fork do
131
- m.synchronize { puts "Didn't get here if you used standard mutex or fork." }
132
- end
133
-
134
- m.synchronize { puts "Got here." }
135
-
136
- Process.wait
137
- end
data/rakefile DELETED
@@ -1,41 +0,0 @@
1
- # Look in the tasks/setup.rb file for the various options that can be
2
- # configured in this Rakefile. The .rake files in the tasks directory
3
- # are where the options are used.
4
-
5
- begin
6
- require 'bones'
7
- Bones.setup
8
- rescue LoadError
9
- begin
10
- load 'tasks/setup.rb'
11
- rescue LoadError
12
- raise RuntimeError, '### please install the "bones" gem ###'
13
- end
14
- end
15
-
16
- ensure_in_path 'lib'
17
- require 'fsdb'
18
-
19
- #task :default => 'spec:run'
20
-
21
- PROJ.name = 'fsdb'
22
- PROJ.authors = 'Joel VanderWerf'
23
- PROJ.email = 'vjoel@users.sourceforge.net'
24
- PROJ.url = 'http://rubyforge.org/projects/fsdb/'
25
- PROJ.version = FSDB::VERSION
26
- PROJ.rubyforge.name = 'fsdb'
27
- PROJ.summary = "File System Database"
28
- PROJ.description = <<END
29
- A file system data base. Provides a thread-safe, process-safe Database class.
30
- Each entry is a separate file referenced by its relative path. Allows multiple
31
- file formats and serialization methods. Pure ruby and very light weight.
32
- END
33
- PROJ.changes = File.read(PROJ.history_file)[/^\w.*?(?=^\w)/m]
34
- PROJ.exclude << %w{ junk misc }
35
-
36
- PROJ.spec.opts << '--color'
37
- PROJ.test.files = Dir["test/*.rb"].select {|f| File.executable? f} ## ?
38
-
39
- task :release => ["gem:release", "doc:release"]
40
-
41
- # EOF
@@ -1,80 +0,0 @@
1
-
2
- begin
3
- require 'bones/smtp_tls'
4
- rescue LoadError
5
- require 'net/smtp'
6
- end
7
- require 'time'
8
-
9
- namespace :ann do
10
-
11
- # A prerequisites task that all other tasks depend upon
12
- task :prereqs
13
-
14
- file PROJ.ann.file do
15
- ann = PROJ.ann
16
- puts "Generating #{ann.file}"
17
- File.open(ann.file,'w') do |fd|
18
- fd.puts("#{PROJ.name} version #{PROJ.version}")
19
- fd.puts(" by #{Array(PROJ.authors).first}") if PROJ.authors
20
- fd.puts(" #{PROJ.url}") if PROJ.url.valid?
21
- fd.puts(" (the \"#{PROJ.release_name}\" release)") if PROJ.release_name
22
- fd.puts
23
- fd.puts("== DESCRIPTION")
24
- fd.puts
25
- fd.puts(PROJ.description)
26
- fd.puts
27
- fd.puts(PROJ.changes.sub(%r/^.*$/, '== CHANGES'))
28
- fd.puts
29
- ann.paragraphs.each do |p|
30
- fd.puts "== #{p.upcase}"
31
- fd.puts
32
- fd.puts paragraphs_of(PROJ.readme_file, p).join("\n\n")
33
- fd.puts
34
- end
35
- fd.puts ann.text if ann.text
36
- end
37
- end
38
-
39
- desc "Create an announcement file"
40
- task :announcement => ['ann:prereqs', PROJ.ann.file]
41
-
42
- desc "Send an email announcement"
43
- task :email => ['ann:prereqs', PROJ.ann.file] do
44
- ann = PROJ.ann
45
- from = ann.email[:from] || Array(PROJ.authors).first || PROJ.email
46
- to = Array(ann.email[:to])
47
-
48
- ### build a mail header for RFC 822
49
- rfc822msg = "From: #{from}\n"
50
- rfc822msg << "To: #{to.join(',')}\n"
51
- rfc822msg << "Subject: [ANN] #{PROJ.name} #{PROJ.version}"
52
- rfc822msg << " (#{PROJ.release_name})" if PROJ.release_name
53
- rfc822msg << "\n"
54
- rfc822msg << "Date: #{Time.new.rfc822}\n"
55
- rfc822msg << "Message-Id: "
56
- rfc822msg << "<#{"%.8f" % Time.now.to_f}@#{ann.email[:domain]}>\n\n"
57
- rfc822msg << File.read(ann.file)
58
-
59
- params = [:server, :port, :domain, :acct, :passwd, :authtype].map do |key|
60
- ann.email[key]
61
- end
62
-
63
- params[3] = PROJ.email if params[3].nil?
64
-
65
- if params[4].nil?
66
- STDOUT.write "Please enter your e-mail password (#{params[3]}): "
67
- params[4] = STDIN.gets.chomp
68
- end
69
-
70
- ### send email
71
- Net::SMTP.start(*params) {|smtp| smtp.sendmail(rfc822msg, from, to)}
72
- end
73
- end # namespace :ann
74
-
75
- desc 'Alias to ann:announcement'
76
- task :ann => 'ann:announcement'
77
-
78
- CLOBBER << PROJ.ann.file
79
-
80
- # EOF
@@ -1,20 +0,0 @@
1
-
2
- if HAVE_BONES
3
-
4
- namespace :bones do
5
-
6
- desc 'Show the PROJ open struct'
7
- task :debug do |t|
8
- atr = if t.application.top_level_tasks.length == 2
9
- t.application.top_level_tasks.pop
10
- end
11
-
12
- if atr then Bones::Debug.show_attr(PROJ, atr)
13
- else Bones::Debug.show PROJ end
14
- end
15
-
16
- end # namespace :bones
17
-
18
- end # HAVE_BONES
19
-
20
- # EOF
@@ -1,201 +0,0 @@
1
-
2
- require 'find'
3
- require 'rake/packagetask'
4
- require 'rubygems/user_interaction'
5
- require 'rubygems/builder'
6
-
7
- module Bones
8
- class GemPackageTask < Rake::PackageTask
9
- # Ruby GEM spec containing the metadata for this package. The
10
- # name, version and package_files are automatically determined
11
- # from the GEM spec and don't need to be explicitly provided.
12
- #
13
- attr_accessor :gem_spec
14
-
15
- # Tasks from the Bones gem directory
16
- attr_reader :bones_files
17
-
18
- # Create a GEM Package task library. Automatically define the gem
19
- # if a block is given. If no block is supplied, then +define+
20
- # needs to be called to define the task.
21
- #
22
- def initialize(gem_spec)
23
- init(gem_spec)
24
- yield self if block_given?
25
- define if block_given?
26
- end
27
-
28
- # Initialization tasks without the "yield self" or define
29
- # operations.
30
- #
31
- def init(gem)
32
- super(gem.name, gem.version)
33
- @gem_spec = gem
34
- @package_files += gem_spec.files if gem_spec.files
35
- @bones_files = []
36
-
37
- local_setup = File.join(Dir.pwd, %w[tasks setup.rb])
38
- if !test(?e, local_setup)
39
- Dir.glob(::Bones.path(%w[lib bones tasks *])).each {|fn| bones_files << fn}
40
- end
41
- end
42
-
43
- # Create the Rake tasks and actions specified by this
44
- # GemPackageTask. (+define+ is automatically called if a block is
45
- # given to +new+).
46
- #
47
- def define
48
- super
49
- task :prereqs
50
- task :package => ['gem:prereqs', "#{package_dir_path}/#{gem_file}"]
51
- file "#{package_dir_path}/#{gem_file}" => [package_dir_path] + package_files + bones_files do
52
- when_writing("Creating GEM") {
53
- chdir(package_dir_path) do
54
- Gem::Builder.new(gem_spec).build
55
- verbose(true) {
56
- mv gem_file, "../#{gem_file}"
57
- }
58
- end
59
- }
60
- end
61
-
62
- file package_dir_path => bones_files do
63
- mkdir_p package_dir rescue nil
64
-
65
- gem_spec.files = (gem_spec.files +
66
- bones_files.map {|fn| File.join('tasks', File.basename(fn))}).sort
67
-
68
- bones_files.each do |fn|
69
- base_fn = File.join('tasks', File.basename(fn))
70
- f = File.join(package_dir_path, base_fn)
71
- fdir = File.dirname(f)
72
- mkdir_p(fdir) if !File.exist?(fdir)
73
- if File.directory?(fn)
74
- mkdir_p(f)
75
- else
76
- raise "file name conflict for '#{base_fn}' (conflicts with '#{fn}')" if test(?e, f)
77
- safe_ln(fn, f)
78
- end
79
- end
80
- end
81
- end
82
-
83
- def gem_file
84
- if @gem_spec.platform == Gem::Platform::RUBY
85
- "#{package_name}.gem"
86
- else
87
- "#{package_name}-#{@gem_spec.platform}.gem"
88
- end
89
- end
90
- end # class GemPackageTask
91
- end # module Bones
92
-
93
- namespace :gem do
94
-
95
- PROJ.gem._spec = Gem::Specification.new do |s|
96
- s.name = PROJ.name
97
- s.version = PROJ.version
98
- s.summary = PROJ.summary
99
- s.authors = Array(PROJ.authors)
100
- s.email = PROJ.email
101
- s.homepage = Array(PROJ.url).first
102
- s.rubyforge_project = PROJ.rubyforge.name
103
-
104
- s.description = PROJ.description
105
-
106
- PROJ.gem.dependencies.each do |dep|
107
- s.add_dependency(*dep)
108
- end
109
-
110
- PROJ.gem.development_dependencies.each do |dep|
111
- s.add_development_dependency(*dep)
112
- end
113
-
114
- s.files = PROJ.gem.files
115
- s.executables = PROJ.gem.executables.map {|fn| File.basename(fn)}
116
- s.extensions = PROJ.gem.files.grep %r/extconf\.rb$/
117
-
118
- s.bindir = 'bin'
119
- dirs = Dir["{#{PROJ.libs.join(',')}}"]
120
- s.require_paths = dirs unless dirs.empty?
121
-
122
- incl = Regexp.new(PROJ.rdoc.include.join('|'))
123
- excl = PROJ.rdoc.exclude.dup.concat %w[\.rb$ ^(\.\/|\/)?ext]
124
- excl = Regexp.new(excl.join('|'))
125
- rdoc_files = PROJ.gem.files.find_all do |fn|
126
- case fn
127
- when excl; false
128
- when incl; true
129
- else false end
130
- end
131
- s.rdoc_options = PROJ.rdoc.opts + ['--main', PROJ.rdoc.main]
132
- s.extra_rdoc_files = rdoc_files
133
- s.has_rdoc = true
134
-
135
- if test ?f, PROJ.test.file
136
- s.test_file = PROJ.test.file
137
- else
138
- s.test_files = PROJ.test.files.to_a
139
- end
140
-
141
- # Do any extra stuff the user wants
142
- PROJ.gem.extras.each do |msg, val|
143
- case val
144
- when Proc
145
- val.call(s.send(msg))
146
- else
147
- s.send "#{msg}=", val
148
- end
149
- end
150
- end # Gem::Specification.new
151
-
152
- Bones::GemPackageTask.new(PROJ.gem._spec) do |pkg|
153
- pkg.need_tar = PROJ.gem.need_tar
154
- pkg.need_zip = PROJ.gem.need_zip
155
- end
156
-
157
- desc 'Show information about the gem'
158
- task :debug => 'gem:prereqs' do
159
- puts PROJ.gem._spec.to_ruby
160
- end
161
-
162
- desc 'Write the gemspec '
163
- task :spec => 'gem:prereqs' do
164
- File.open("#{PROJ.name}.gemspec", 'w') do |f|
165
- f.write PROJ.gem._spec.to_ruby
166
- end
167
- end
168
-
169
- desc 'Install the gem'
170
- task :install => [:clobber, 'gem:package'] do
171
- sh "#{SUDO} #{GEM} install --local pkg/#{PROJ.gem._spec.full_name}"
172
-
173
- # use this version of the command for rubygems > 1.0.0
174
- #sh "#{SUDO} #{GEM} install --no-update-sources pkg/#{PROJ.gem._spec.full_name}"
175
- end
176
-
177
- desc 'Uninstall the gem'
178
- task :uninstall do
179
- installed_list = Gem.source_index.find_name(PROJ.name)
180
- if installed_list and installed_list.collect { |s| s.version.to_s}.include?(PROJ.version) then
181
- sh "#{SUDO} #{GEM} uninstall --version '#{PROJ.version}' --ignore-dependencies --executables #{PROJ.name}"
182
- end
183
- end
184
-
185
- desc 'Reinstall the gem'
186
- task :reinstall => [:uninstall, :install]
187
-
188
- desc 'Cleanup the gem'
189
- task :cleanup do
190
- sh "#{SUDO} #{GEM} cleanup #{PROJ.gem._spec.name}"
191
- end
192
- end # namespace :gem
193
-
194
-
195
- desc 'Alias to gem:package'
196
- task :gem => 'gem:package'
197
-
198
- task :clobber => 'gem:clobber_package'
199
- remove_desc_for_task 'gem:clobber_package'
200
-
201
- # EOF