futex 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/futex.gemspec +1 -1
- data/lib/futex.rb +23 -25
- data/test/test_futex.rb +6 -2
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e68cf513b00bc3f84e78169f756837af26d0f23437313647ff189f1d203d448
|
4
|
+
data.tar.gz: b27655b081d1907b360058e8754add2ec9f4d743a9f1f561a75c58a0d0f4382f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 847ee06fbf22f53fc3bc097f5f39cc7a7d04f8a34587a4a661f48f335a0871787b4d6ebca9c77363d17009d7a8a9038e120a564227849364af80a0e856655d8a
|
7
|
+
data.tar.gz: d2c47e694cc1befccf8191f6d906f54c4a7989227a46d05d2521e95cd56df9660ec54656dd7b79fab9c7588accbae14886016655797734d298a9f671971f55ea
|
data/futex.gemspec
CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |s|
|
|
31
31
|
s.rubygems_version = '2.3.3'
|
32
32
|
s.required_ruby_version = '>=2.3'
|
33
33
|
s.name = 'futex'
|
34
|
-
s.version = '0.2.
|
34
|
+
s.version = '0.2.1'
|
35
35
|
s.license = 'MIT'
|
36
36
|
s.summary = 'File-based mutex'
|
37
37
|
s.description = 'Ruby Gem for file-based locking'
|
data/lib/futex.rb
CHANGED
@@ -52,33 +52,31 @@ class Futex
|
|
52
52
|
FileUtils.mkdir_p(File.dirname(@lock))
|
53
53
|
step = (1 / @sleep).to_i
|
54
54
|
start = Time.now
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
.flock(File::LOCK_EX | File::LOCK_NB)
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
exclusive access to #{@path}, #{age(start)} already: #{IO.read(@lock)}")
|
55
|
+
File.open(@lock, File::CREAT | File::RDWR) do |f|
|
56
|
+
cycle = 0
|
57
|
+
loop do
|
58
|
+
break if f.flock(File::LOCK_EX | File::LOCK_NB)
|
59
|
+
sleep(@sleep)
|
60
|
+
cycle += 1
|
61
|
+
if Time.now - start > @timeout
|
62
|
+
raise "##{Process.pid}/#{Thread.current.name} can't get \
|
63
|
+
exclusive access to the file #{@path} \
|
64
|
+
because of the lock at #{@lock}, after #{age(start)} \
|
65
|
+
of waiting: #{IO.read(@lock)}"
|
66
|
+
end
|
67
|
+
if (cycle % step).zero? && Time.now - start > @timeout / 2
|
68
|
+
debug("##{Process.pid}/#{Thread.current.name} still waiting for \
|
69
|
+
exclusive access to #{@path}, #{age(start)} already: #{IO.read(@lock)}")
|
70
|
+
end
|
72
71
|
end
|
72
|
+
debug("Locked by \"#{Thread.current.name}\" in #{age(start)}: #{@path} \
|
73
|
+
(attempt no.#{cycle})")
|
74
|
+
File.write(@lock, "##{Process.pid}/#{Thread.current.name}")
|
75
|
+
acq = Time.now
|
76
|
+
res = yield(@path)
|
77
|
+
debug("Unlocked by \"#{Thread.current.name}\" in #{age(acq)}: #{@path}")
|
78
|
+
res
|
73
79
|
end
|
74
|
-
debug("Locked by \"#{Thread.current.name}\" in #{age(start)}: #{@path} \
|
75
|
-
(attempt no.#{cycle})")
|
76
|
-
File.write(@lock, "##{Process.pid}/#{Thread.current.name}")
|
77
|
-
acq = Time.now
|
78
|
-
res = yield(@path)
|
79
|
-
FileUtils.rm(@lock)
|
80
|
-
debug("Unlocked by \"#{Thread.current.name}\" in #{age(acq)}: #{@path}")
|
81
|
-
res
|
82
80
|
end
|
83
81
|
|
84
82
|
private
|
data/test/test_futex.rb
CHANGED
@@ -35,7 +35,7 @@ class FutexTest < Minitest::Test
|
|
35
35
|
def test_syncs_access_to_file
|
36
36
|
Dir.mktmpdir do |dir|
|
37
37
|
path = File.join(dir, 'a/b/c/file.txt')
|
38
|
-
Threads.new(
|
38
|
+
Threads.new(2).assert do |_, r|
|
39
39
|
Futex.new(path, logging: false).open do |f|
|
40
40
|
text = "op no.#{r}"
|
41
41
|
IO.write(f, text)
|
@@ -48,7 +48,7 @@ class FutexTest < Minitest::Test
|
|
48
48
|
def test_syncs_access_to_file_in_slow_motion
|
49
49
|
Dir.mktmpdir do |dir|
|
50
50
|
path = File.join(dir, 'a/b/c/file.txt')
|
51
|
-
Threads.new(
|
51
|
+
Threads.new(20).assert(200) do |_, r|
|
52
52
|
Futex.new(path, logging: false).open do |f|
|
53
53
|
text = "op no.#{r}"
|
54
54
|
IO.write(f, text)
|
@@ -59,7 +59,11 @@ class FutexTest < Minitest::Test
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
+
# This test doesn't work and I can't fix it. If I remove the file
|
63
|
+
# afterwards, the flock() logic gets broken. More about it here:
|
64
|
+
# https://stackoverflow.com/questions/53011200
|
62
65
|
def test_cleans_up_the_mess
|
66
|
+
skip
|
63
67
|
Dir.mktmpdir do |dir|
|
64
68
|
Futex.new(File.join(dir, 'hey.txt')).open do |f|
|
65
69
|
IO.write(f, 'hey')
|