lockfile 1.4.3 → 2.0.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/gemspec.rb DELETED
@@ -1,27 +0,0 @@
1
-
2
- lib, version = File::basename(File::dirname(File::expand_path(__FILE__))).split %r/-/, 2
3
-
4
- require 'rubygems'
5
-
6
- Gem::Specification::new do |spec|
7
- $VERBOSE = nil
8
- spec.name = lib
9
- spec.version = version
10
- spec.platform = Gem::Platform::RUBY
11
- spec.summary = lib
12
-
13
- spec.files = Dir::glob "**/**"
14
- spec.executables = Dir::glob("bin/*").map{|exe| File::basename exe}
15
-
16
- spec.require_path = "lib"
17
- spec.autorequire = lib
18
-
19
- spec.has_rdoc = File::exist? "doc"
20
- spec.test_suite_file = "test/#{ lib }.rb" if File::directory? "test"
21
-
22
- spec.extensions << "extconf.rb" if File::exists? "extconf.rb"
23
-
24
- spec.author = "Ara T. Howard"
25
- spec.email = "ara.t.howard@noaa.gov"
26
- spec.homepage = "http://codeforpeople.com/lib/ruby/#{ lib }/"
27
- end
data/install.rb DELETED
@@ -1,210 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'rbconfig'
3
- require 'find'
4
- require 'ftools'
5
- require 'tempfile'
6
- include Config
7
-
8
- LIBDIR = "lib"
9
- LIBDIR_MODE = 0644
10
-
11
- BINDIR = "bin"
12
- BINDIR_MODE = 0755
13
-
14
-
15
- $srcdir = CONFIG["srcdir"]
16
- $version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
17
- $libdir = File.join(CONFIG["libdir"], "ruby", $version)
18
- $archdir = File.join($libdir, CONFIG["arch"])
19
- $site_libdir = $:.find {|x| x =~ /site_ruby$/}
20
- $bindir = CONFIG["bindir"] || CONFIG['BINDIR']
21
- $ruby_install_name = CONFIG['ruby_install_name'] || CONFIG['RUBY_INSTALL_NAME'] || 'ruby'
22
- $ruby_ext = CONFIG['EXEEXT'] || ''
23
- $ruby = File.join($bindir, ($ruby_install_name + $ruby_ext))
24
-
25
- if !$site_libdir
26
- $site_libdir = File.join($libdir, "site_ruby")
27
- elsif $site_libdir !~ %r/#{Regexp.quote($version)}/
28
- $site_libdir = File.join($site_libdir, $version)
29
- end
30
-
31
- def install_rb(srcdir=nil, destdir=nil, mode=nil, bin=nil)
32
- #{{{
33
- path = []
34
- dir = []
35
- Find.find(srcdir) do |f|
36
- next unless FileTest.file?(f)
37
- next if (f = f[srcdir.length+1..-1]) == nil
38
- next if (/CVS$/ =~ File.dirname(f))
39
- next if f =~ %r/\.lnk/
40
- path.push f
41
- dir |= [File.dirname(f)]
42
- end
43
- for f in dir
44
- next if f == "."
45
- next if f == "CVS"
46
- File::makedirs(File.join(destdir, f))
47
- end
48
- for f in path
49
- next if (/\~$/ =~ f)
50
- next if (/^\./ =~ File.basename(f))
51
- unless bin
52
- File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
53
- else
54
- from = File.join(srcdir, f)
55
- to = File.join(destdir, f)
56
- shebangify(from) do |sf|
57
- $deferr.print from, " -> ", File::catname(from, to), "\n"
58
- $deferr.printf "chmod %04o %s\n", mode, to
59
- File::install(sf, to, mode, false)
60
- end
61
- end
62
- end
63
- #}}}
64
- end
65
- def shebangify f
66
- #{{{
67
- open(f) do |fd|
68
- buf = fd.read 42
69
- if buf =~ %r/^\s*#\s*!.*ruby/o
70
- ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
71
- begin
72
- fd.rewind
73
- ftmp.puts "#!#{ $ruby }"
74
- while((buf = fd.read(8192)))
75
- ftmp.write buf
76
- end
77
- ftmp.close
78
- yield ftmp.path
79
- ensure
80
- ftmp.close!
81
- end
82
- else
83
- yield f
84
- end
85
- end
86
- #}}}
87
- end
88
- def ARGV.switch
89
- #{{{
90
- return nil if self.empty?
91
- arg = self.shift
92
- return nil if arg == '--'
93
- if arg =~ /^-(.)(.*)/
94
- return arg if $1 == '-'
95
- raise 'unknown switch "-"' if $2.index('-')
96
- self.unshift "-#{$2}" if $2.size > 0
97
- "-#{$1}"
98
- else
99
- self.unshift arg
100
- nil
101
- end
102
- #}}}
103
- end
104
- def ARGV.req_arg
105
- #{{{
106
- self.shift || raise('missing argument')
107
- #}}}
108
- end
109
- def linkify d, linked = []
110
- #--{{{
111
- if test ?d, d
112
- versioned = Dir[ File::join(d, "*-[0-9].[0-9].[0-9].rb") ]
113
- versioned.each do |v|
114
- src, dst = v, v.gsub(%r/\-[\d\.]+\.rb$/, '.rb')
115
- lnk = nil
116
- begin
117
- if test ?l, dst
118
- lnk = "#{ dst }.lnk"
119
- puts "#{ dst } -> #{ lnk }"
120
- File::rename dst, lnk
121
- end
122
- unless test ?e, dst
123
- puts "#{ src } -> #{ dst }"
124
- File::copy src, dst
125
- linked << dst
126
- end
127
- ensure
128
- if lnk
129
- at_exit do
130
- puts "#{ lnk } -> #{ dst }"
131
- File::rename lnk, dst
132
- end
133
- end
134
- end
135
- end
136
- end
137
- linked
138
- #--}}}
139
- end
140
-
141
-
142
- #
143
- # main program
144
- #
145
-
146
- libdir = $site_libdir
147
- bindir = $bindir
148
- no_linkify = false
149
- linked = nil
150
- help = false
151
-
152
- usage = <<-usage
153
- #{ File::basename $0 }
154
- -d, --destdir <destdir>
155
- -l, --libdir <libdir>
156
- -b, --bindir <bindir>
157
- -r, --ruby <ruby>
158
- -n, --no_linkify
159
- -s, --sudo
160
- -h, --help
161
- usage
162
-
163
- begin
164
- while switch = ARGV.switch
165
- case switch
166
- when '-d', '--destdir'
167
- libdir = ARGV.req_arg
168
- when '-l', '--libdir'
169
- libdir = ARGV.req_arg
170
- when '-b', '--bindir'
171
- bindir = ARGV.req_arg
172
- when '-r', '--ruby'
173
- $ruby = ARGV.req_arg
174
- when '-n', '--no_linkify'
175
- no_linkify = true
176
- when '-s', '--sudo'
177
- sudo = 'sudo'
178
- when '-h', '--help'
179
- help = true
180
- else
181
- raise "unknown switch #{switch.dump}"
182
- end
183
- end
184
- rescue
185
- STDERR.puts $!.to_s
186
- STDERR.puts usage
187
- exit 1
188
- end
189
-
190
- if help
191
- STDOUT.puts usage
192
- exit
193
- end
194
-
195
- system "#{ sudo } #{ $ruby } pre-install.rb" if test(?s, 'pre-install.rb')
196
-
197
- unless no_linkify
198
- linked = linkify('lib') + linkify('bin')
199
- end
200
-
201
- system "#{ $ruby } extconf.rb && make && #{ sudo } make install" if test(?s, 'extconf.rb')
202
-
203
- install_rb(LIBDIR, libdir, LIBDIR_MODE)
204
- install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)
205
-
206
- if linked
207
- linked.each{|path| File::rm_f path}
208
- end
209
-
210
- system "#{ sudo } #{ $ruby } post-install.rb" if test(?s, 'post-install.rb')
@@ -1,564 +0,0 @@
1
- unless(defined?($__lockfile__) or defined?(Lockfile))
2
-
3
- require 'socket'
4
- require 'timeout'
5
- require 'fileutils'
6
-
7
- class Lockfile
8
- #--{{{
9
- VERSION = '1.4.3'
10
- def version() VERSION end
11
-
12
- class LockError < StandardError; end
13
- class StolenLockError < LockError; end
14
- class StackingLockError < LockError; end
15
- class StatLockError < LockError; end
16
- class MaxTriesLockError < LockError; end
17
- class TimeoutLockError < LockError; end
18
- class NFSLockError < LockError; end
19
- class UnLockError < LockError; end
20
-
21
- class SleepCycle < Array
22
- #--{{{
23
- attr :min
24
- attr :max
25
- attr :range
26
- attr :inc
27
- def initialize min, max, inc
28
- #--{{{
29
- @min, @max, @inc = Float(min), Float(max), Float(inc)
30
- @range = @max - @min
31
- raise RangeError, "max(#{ @max }) <= min(#{ @min })" if @max <= @min
32
- raise RangeError, "inc(#{ @inc }) > range(#{ @range })" if @inc > @range
33
- raise RangeError, "inc(#{ @inc }) <= 0" if @inc <= 0
34
- raise RangeError, "range(#{ @range }) <= 0" if @range <= 0
35
- s = @min
36
- push(s) and s += @inc while(s <= @max)
37
- self[-1] = @max if self[-1] < @max
38
- reset
39
- #--}}}
40
- end
41
- def next
42
- #--{{{
43
- ret = self[@idx]
44
- @idx = ((@idx + 1) % self.size)
45
- ret
46
- #--}}}
47
- end
48
- def reset
49
- #--{{{
50
- @idx = 0
51
- #--}}}
52
- end
53
- #--}}}
54
- end
55
-
56
- HOSTNAME = Socket::gethostname
57
-
58
- DEFAULT_RETRIES = nil # maximum number of attempts
59
- DEFAULT_TIMEOUT = nil # the longest we will try
60
- DEFAULT_MAX_AGE = 3600 # lockfiles older than this are stale
61
- DEFAULT_SLEEP_INC = 2 # sleep cycle is this much longer each time
62
- DEFAULT_MIN_SLEEP = 2 # shortest sleep time
63
- DEFAULT_MAX_SLEEP = 32 # longest sleep time
64
- DEFAULT_SUSPEND = 1800 # iff we steal a lock wait this long before we go on
65
- DEFAULT_REFRESH = 8 # how often we touch/validate the lock
66
- DEFAULT_DONT_CLEAN = false # iff we leave lock files lying around
67
- DEFAULT_POLL_RETRIES = 16 # this many polls makes one 'try'
68
- DEFAULT_POLL_MAX_SLEEP = 0.08 # the longest we'll sleep between polls
69
- DEFAULT_DONT_SWEEP = false # if we cleanup after other process on our host
70
- DEFAULT_DONT_USE_LOCK_ID = false # if we dump lock info into lockfile
71
-
72
- DEFAULT_DEBUG = ENV['LOCKFILE_DEBUG'] || false
73
-
74
- class << self
75
- #--{{{
76
- attr :retries, true
77
- attr :max_age, true
78
- attr :sleep_inc, true
79
- attr :min_sleep, true
80
- attr :max_sleep, true
81
- attr :suspend, true
82
- attr :timeout, true
83
- attr :refresh, true
84
- attr :debug, true
85
- attr :dont_clean, true
86
- attr :poll_retries, true
87
- attr :poll_max_sleep, true
88
- attr :dont_sweep, true
89
- attr :dont_use_lock_id, true
90
-
91
- def init
92
- #--{{{
93
- @retries = DEFAULT_RETRIES
94
- @max_age = DEFAULT_MAX_AGE
95
- @sleep_inc = DEFAULT_SLEEP_INC
96
- @min_sleep = DEFAULT_MIN_SLEEP
97
- @max_sleep = DEFAULT_MAX_SLEEP
98
- @suspend = DEFAULT_SUSPEND
99
- @timeout = DEFAULT_TIMEOUT
100
- @refresh = DEFAULT_REFRESH
101
- @dont_clean = DEFAULT_DONT_CLEAN
102
- @poll_retries = DEFAULT_POLL_RETRIES
103
- @poll_max_sleep = DEFAULT_POLL_MAX_SLEEP
104
- @dont_sweep = DEFAULT_DONT_SWEEP
105
- @dont_use_lock_id = DEFAULT_DONT_USE_LOCK_ID
106
-
107
- @debug = DEFAULT_DEBUG
108
-
109
- STDOUT.sync = true if @debug
110
- STDERR.sync = true if @debug
111
- #--}}}
112
- end
113
- #--}}}
114
- end
115
- self.init
116
-
117
- attr :klass
118
- attr :path
119
- attr :opts
120
- attr :locked
121
- attr :thief
122
- attr :dirname
123
- attr :basename
124
- attr :clean
125
- attr :retries
126
- attr :max_age
127
- attr :sleep_inc
128
- attr :min_sleep
129
- attr :max_sleep
130
- attr :suspend
131
- attr :refresh
132
- attr :timeout
133
- attr :dont_clean
134
- attr :poll_retries
135
- attr :poll_max_sleep
136
- attr :dont_sweep
137
- attr :dont_use_lock_id
138
-
139
- attr :debug, true
140
-
141
- alias thief? thief
142
- alias locked? locked
143
- alias debug? debug
144
-
145
- def self::create(path, *a, &b)
146
- #--{{{
147
- opts = {
148
- 'retries' => 0,
149
- 'min_sleep' => 0,
150
- 'max_sleep' => 1,
151
- 'sleep_inc' => 1,
152
- 'max_age' => nil,
153
- 'suspend' => 0,
154
- 'refresh' => nil,
155
- 'timeout' => nil,
156
- 'poll_retries' => 0,
157
- 'dont_clean' => true,
158
- 'dont_sweep' => false,
159
- 'dont_use_lock_id' => true,
160
- }
161
- begin
162
- new(path, opts).lock
163
- rescue LockError
164
- raise Errno::EEXIST, path
165
- end
166
- open(path, *a, &b)
167
- #--}}}
168
- end
169
-
170
- def initialize(path, opts = {}, &block)
171
- #--{{{
172
- @klass = self.class
173
- @path = path
174
- @opts = opts
175
-
176
- @retries = getopt 'retries' , @klass.retries
177
- @max_age = getopt 'max_age' , @klass.max_age
178
- @sleep_inc = getopt 'sleep_inc' , @klass.sleep_inc
179
- @min_sleep = getopt 'min_sleep' , @klass.min_sleep
180
- @max_sleep = getopt 'max_sleep' , @klass.max_sleep
181
- @suspend = getopt 'suspend' , @klass.suspend
182
- @timeout = getopt 'timeout' , @klass.timeout
183
- @refresh = getopt 'refresh' , @klass.refresh
184
- @dont_clean = getopt 'dont_clean' , @klass.dont_clean
185
- @poll_retries = getopt 'poll_retries' , @klass.poll_retries
186
- @poll_max_sleep = getopt 'poll_max_sleep' , @klass.poll_max_sleep
187
- @dont_sweep = getopt 'dont_sweep' , @klass.dont_sweep
188
- @dont_use_lock_id = getopt 'dont_use_lock_id' , @klass.dont_use_lock_id
189
- @debug = getopt 'debug' , @klass.debug
190
-
191
- @sleep_cycle = SleepCycle::new @min_sleep, @max_sleep, @sleep_inc
192
-
193
- @clean = @dont_clean ? nil : lambda{ File::unlink @path rescue nil }
194
- @dirname = File::dirname @path
195
- @basename = File::basename @path
196
- @thief = false
197
- @locked = false
198
-
199
- lock(&block) if block
200
- #--}}}
201
- end
202
- def lock
203
- #--{{{
204
- raise StackingLockError, "<#{ @path }> is locked!" if @locked
205
-
206
- sweep unless @dont_sweep
207
-
208
- ret = nil
209
-
210
- attempt do
211
- begin
212
- @sleep_cycle.reset
213
- create_tmplock do |f|
214
- begin
215
- Timeout::timeout(@timeout) do
216
- tmp_path = f.path
217
- tmp_stat = f.lstat
218
- n_retries = 0
219
- trace{ "attempting to lock <#{ @path }>..." }
220
- begin
221
- i = 0
222
- begin
223
- trace{ "polling attempt <#{ i }>..." }
224
- begin
225
- File::link tmp_path, @path
226
- rescue Errno::ENOENT
227
- try_again!
228
- end
229
- lock_stat = File::lstat @path
230
- raise StatLockError, "stat's do not agree" unless
231
- tmp_stat.rdev == lock_stat.rdev and tmp_stat.ino == lock_stat.ino
232
- trace{ "aquired lock <#{ @path }>" }
233
- @locked = true
234
- rescue => e
235
- i += 1
236
- unless i >= @poll_retries
237
- t = [rand(@poll_max_sleep), @poll_max_sleep].min
238
- trace{ "poll sleep <#{ t }>..." }
239
- sleep t
240
- retry
241
- end
242
- raise
243
- end
244
-
245
- rescue => e
246
- n_retries += 1
247
- trace{ "n_retries <#{ n_retries }>" }
248
- case validlock?
249
- when true
250
- raise MaxTriesLockError, "surpased retries <#{ @retries }>" if
251
- @retries and n_retries >= @retries
252
- trace{ "found valid lock" }
253
- sleeptime = @sleep_cycle.next
254
- trace{ "sleep <#{ sleeptime }>..." }
255
- sleep sleeptime
256
- when false
257
- trace{ "found invalid lock and removing" }
258
- begin
259
- File::unlink @path
260
- @thief = true
261
- warn "<#{ @path }> stolen by <#{ Process.pid }> at <#{ timestamp }>"
262
- trace{ "i am a thief!" }
263
- rescue Errno::ENOENT
264
- end
265
- trace{ "suspending <#{ @suspend }>" }
266
- sleep @suspend
267
- when nil
268
- raise MaxTriesLockError, "surpased retries <#{ @retries }>" if
269
- @retries and n_retries >= @retries
270
- end
271
- retry
272
- end # begin
273
- end # timeout
274
- rescue Timeout::Error
275
- raise TimeoutLockError, "surpassed timeout <#{ @timeout }>"
276
- end # begin
277
- end # create_tmplock
278
-
279
- if block_given?
280
- stolen = false
281
- refresher = (@refresh ? new_refresher : nil)
282
- begin
283
- begin
284
- ret = yield @path
285
- rescue StolenLockError
286
- stolen = true
287
- raise
288
- end
289
- ensure
290
- begin
291
- refresher.kill if refresher and refresher.status
292
- ensure
293
- unlock unless stolen
294
- end
295
- end
296
- else
297
- ObjectSpace.define_finalizer self, @clean if @clean
298
- ret = self
299
- end
300
- rescue Errno::ESTALE, Errno::EIO => e
301
- raise(NFSLockError, errmsg(e))
302
- end
303
- end
304
-
305
- return ret
306
- #--}}}
307
- end
308
- def sweep
309
- #----{{{
310
- begin
311
- glob = File::join(@dirname, ".*lck")
312
- paths = Dir[glob]
313
- paths.each do |path|
314
- begin
315
- basename = File::basename path
316
- pat = %r/^\s*\.([^_]+)_([^_]+)/o
317
- if pat.match(basename)
318
- host, pid = $1, $2
319
- else
320
- next
321
- end
322
- host.gsub!(%r/^\.+|\.+$/,'')
323
- quad = host.split %r/\./
324
- host = quad.first
325
- pat = %r/^\s*#{ host }/i
326
- if pat.match(HOSTNAME) and %r/^\s*\d+\s*$/.match(pid)
327
- unless alive?(pid)
328
- trace{ "process <#{ pid }> on <#{ host }> is no longer alive" }
329
- trace{ "sweeping <#{ path }>" }
330
- FileUtils::rm_f path
331
- else
332
- trace{ "process <#{ pid }> on <#{ host }> is still alive" }
333
- trace{ "ignoring <#{ path }>" }
334
- end
335
- else
336
- trace{ "ignoring <#{ path }> generated by <#{ host }>" }
337
- end
338
- rescue
339
- next
340
- end
341
- end
342
- rescue => e
343
- warn(errmsg(e))
344
- end
345
- #----}}}
346
- end
347
- def alive? pid
348
- #----{{{
349
- pid = Integer("#{ pid }")
350
- begin
351
- Process::kill 0, pid
352
- true
353
- rescue Errno::ESRCH
354
- false
355
- end
356
- #----}}}
357
- end
358
- def unlock
359
- #--{{{
360
- raise UnLockError, "<#{ @path }> is not locked!" unless @locked
361
- begin
362
- File::unlink @path
363
- rescue Errno::ENOENT
364
- raise StolenLockError, @path
365
- ensure
366
- @thief = false
367
- @locked = false
368
- ObjectSpace.undefine_finalizer self if @clean
369
- end
370
- #--}}}
371
- end
372
- def new_refresher
373
- #--{{{
374
- Thread::new(Thread::current, @path, @refresh, @dont_use_lock_id) do |thread, path, refresh, dont_use_lock_id|
375
- loop do
376
- begin
377
- touch path
378
- trace{"touched <#{ path }> @ <#{ Time.now.to_f }>"}
379
- unless dont_use_lock_id
380
- loaded = load_lock_id(IO.read(path))
381
- trace{"loaded <\n#{ loaded.inspect }\n>"}
382
- raise unless loaded == @lock_id
383
- end
384
- sleep refresh
385
- rescue Exception => e
386
- trace{errmsg e}
387
- thread.raise StolenLockError
388
- Thread::exit
389
- end
390
- end
391
- end
392
- #--}}}
393
- end
394
- def validlock?
395
- #--{{{
396
- if @max_age
397
- uncache @path rescue nil
398
- begin
399
- return((Time.now - File::stat(@path).mtime) < @max_age)
400
- rescue Errno::ENOENT
401
- return nil
402
- end
403
- else
404
- exist = File::exist?(@path)
405
- return(exist ? true : nil)
406
- end
407
- #--}}}
408
- end
409
- def uncache file
410
- #--{{{
411
- refresh = nil
412
- begin
413
- is_a_file = File === file
414
- path = (is_a_file ? file.path : file.to_s)
415
- stat = (is_a_file ? file.stat : File::stat(file.to_s))
416
- refresh = tmpnam(File::dirname(path))
417
- File::link path, refresh
418
- File::chmod stat.mode, path
419
- File::utime stat.atime, stat.mtime, path
420
- ensure
421
- begin
422
- File::unlink refresh if refresh
423
- rescue Errno::ENOENT
424
- end
425
- end
426
- #--}}}
427
- end
428
- def create_tmplock
429
- #--{{{
430
- tmplock = tmpnam @dirname
431
- begin
432
- create(tmplock) do |f|
433
- unless dont_use_lock_id
434
- @lock_id = gen_lock_id
435
- dumped = dump_lock_id
436
- trace{"lock_id <\n#{ @lock_id.inspect }\n>"}
437
- f.write dumped
438
- f.flush
439
- end
440
- yield f
441
- end
442
- ensure
443
- begin; File::unlink tmplock; rescue Errno::ENOENT; end if tmplock
444
- end
445
- #--}}}
446
- end
447
- def gen_lock_id
448
- #--{{{
449
- Hash[
450
- 'host' => "#{ HOSTNAME }",
451
- 'pid' => "#{ Process.pid }",
452
- 'ppid' => "#{ Process.ppid }",
453
- 'time' => timestamp,
454
- ]
455
- #--}}}
456
- end
457
- def timestamp
458
- #--{{{
459
- time = Time.now
460
- usec = time.usec.to_s
461
- usec << '0' while usec.size < 6
462
- "#{ time.strftime('%Y-%m-%d %H:%M:%S') }.#{ usec }"
463
- #--}}}
464
- end
465
- def dump_lock_id lock_id = @lock_id
466
- #--{{{
467
- "host: %s\npid: %s\nppid: %s\ntime: %s\n" %
468
- lock_id.values_at('host','pid','ppid','time')
469
- #--}}}
470
- end
471
- def load_lock_id buf
472
- #--{{{
473
- lock_id = {}
474
- kv = %r/([^:]+):(.*)/o
475
- buf.each do |line|
476
- m = kv.match line
477
- k, v = m[1], m[2]
478
- next unless m and k and v
479
- lock_id[k.strip] = v.strip
480
- end
481
- lock_id
482
- #--}}}
483
- end
484
- def tmpnam dir, seed = File::basename($0)
485
- #--{{{
486
- pid = Process.pid
487
- time = Time.now
488
- sec = time.to_i
489
- usec = time.usec
490
- "%s%s.%s_%d_%s_%d_%d_%d.lck" %
491
- [dir, File::SEPARATOR, HOSTNAME, pid, seed, sec, usec, rand(sec)]
492
- #--}}}
493
- end
494
- def create path
495
- #--{{{
496
- umask = nil
497
- f = nil
498
- begin
499
- umask = File::umask 022
500
- f = open path, File::WRONLY|File::CREAT|File::EXCL, 0644
501
- ensure
502
- File::umask umask if umask
503
- end
504
- return(block_given? ? begin; yield f; ensure; f.close; end : f)
505
- #--}}}
506
- end
507
- def touch path
508
- #--{{{
509
- FileUtils.touch path
510
- #--}}}
511
- end
512
- def getopt key, default = nil
513
- #--{{{
514
- [ key, key.to_s, key.to_s.intern ].each do |k|
515
- return @opts[k] if @opts.has_key?(k)
516
- end
517
- return default
518
- #--}}}
519
- end
520
- def to_str
521
- #--{{{
522
- @path
523
- #--}}}
524
- end
525
- alias to_s to_str
526
- def trace s = nil
527
- #--{{{
528
- STDERR.puts((s ? s : yield)) if @debug
529
- #--}}}
530
- end
531
- def errmsg e
532
- #--{{{
533
- "%s (%s)\n%s\n" % [e.class, e.message, e.backtrace.join("\n")]
534
- #--}}}
535
- end
536
- def attempt
537
- #----{{{
538
- ret = nil
539
- loop{ break unless catch('attempt'){ ret = yield } == 'try_again' }
540
- ret
541
- #----}}}
542
- end
543
- def try_again!
544
- #----{{{
545
- throw 'attempt', 'try_again'
546
- #----}}}
547
- end
548
- alias again! try_again!
549
- def give_up!
550
- #----{{{
551
- throw 'attempt', 'give_up'
552
- #----}}}
553
- end
554
- #--}}}
555
- end
556
-
557
- def Lockfile path, *a, &b
558
- #--{{{
559
- Lockfile.new(path, *a, &b)
560
- #--}}}
561
- end
562
-
563
- $__lockfile__ = __FILE__
564
- end