A
Ara.T.Howard
in the code below, i am able to obtain TWO exclusive locks on files using the
following logic:
iff flock(LOCK_EX | LOCK_NB) fails, then open again and retry
this should not be possible should it??
note that the following code SHOULD deadlock - but does not.
CODE:
----CUT----
#!/usr/local/ruby-1.8.0/bin/ruby
threads = []
flags = (File::LOCK_EX | File::LOCK_NB)
system 'touch a b' rescue nil
threads << Thread.new do
%w(a b).each do |path|
fd = open(path)
#until((ret = fd.flock flags)) # this works (deadlock)
until((ret = open(path).flock flags)) # this doesn't
Thread.pass
end
printf "0 LOCK_EX %s <%s>\n", path, ret
sleep 0.5
end
end
threads << Thread.new do
%w(b a).each do |path|
fd = open(path)
#until((ret = fd.flock flags)) # this works (deadlock)
until((ret = open(path).flock flags)) # this doesn't
Thread.pass
end
printf "1 LOCK_EX %s <%s>\n", path, ret
sleep 0.5
end
end
Thread.abort_on_exception = true
threads.map{|thread| thread.join}
----CUT----
OUTPUT:
[ahoward@localhost flock]$ ./flock.rb
0 LOCK_EX a <0>
1 LOCK_EX b <0>
0 LOCK_EX b <0>
1 LOCK_EX a <0>
so, two threads are able to obtain exclusive locks on a file? perhaps i am
making an obvious mistake?? shouldn't each call to open(path).flock be
referring to the same open file table entry and, therefore, not affect the
thread's ability to obtain an LOCK_EX?
-a
====================================
| Ara Howard
| NOAA Forecast Systems Laboratory
| Information and Technology Services
| Data Systems Group
| R/FST 325 Broadway
| Boulder, CO 80305-3328
| Email: (e-mail address removed)
| Phone: 303-497-7238
| Fax: 303-497-7259
| 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 lang in ruby perl; do $lang -e "print \"\x3a\x2d\x29\x0a\""; done'
====================================
following logic:
iff flock(LOCK_EX | LOCK_NB) fails, then open again and retry
this should not be possible should it??
note that the following code SHOULD deadlock - but does not.
CODE:
----CUT----
#!/usr/local/ruby-1.8.0/bin/ruby
threads = []
flags = (File::LOCK_EX | File::LOCK_NB)
system 'touch a b' rescue nil
threads << Thread.new do
%w(a b).each do |path|
fd = open(path)
#until((ret = fd.flock flags)) # this works (deadlock)
until((ret = open(path).flock flags)) # this doesn't
Thread.pass
end
printf "0 LOCK_EX %s <%s>\n", path, ret
sleep 0.5
end
end
threads << Thread.new do
%w(b a).each do |path|
fd = open(path)
#until((ret = fd.flock flags)) # this works (deadlock)
until((ret = open(path).flock flags)) # this doesn't
Thread.pass
end
printf "1 LOCK_EX %s <%s>\n", path, ret
sleep 0.5
end
end
Thread.abort_on_exception = true
threads.map{|thread| thread.join}
----CUT----
OUTPUT:
[ahoward@localhost flock]$ ./flock.rb
0 LOCK_EX a <0>
1 LOCK_EX b <0>
0 LOCK_EX b <0>
1 LOCK_EX a <0>
so, two threads are able to obtain exclusive locks on a file? perhaps i am
making an obvious mistake?? shouldn't each call to open(path).flock be
referring to the same open file table entry and, therefore, not affect the
thread's ability to obtain an LOCK_EX?
-a
====================================
| Ara Howard
| NOAA Forecast Systems Laboratory
| Information and Technology Services
| Data Systems Group
| R/FST 325 Broadway
| Boulder, CO 80305-3328
| Email: (e-mail address removed)
| Phone: 303-497-7238
| Fax: 303-497-7259
| 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 lang in ruby perl; do $lang -e "print \"\x3a\x2d\x29\x0a\""; done'
====================================