Hello again,

I repost about this thread because it seems to be a bug in ruby and
nobody replied.
I made a simplier script to test it. I think this use of flock is valid
and should not block all threads (other threads not concerned by the
lock are also blocked).
I tested it with fork instead of threads and it seems to work.
File.flock might not be thread safe?
The script creates 2 threads that infinitly lock and read a file. Each
thread displays what it does before the function call and the result is:

mike@photon:~$ ruby -vw tmp/flock.rb
ruby 1.6.4 (2001-06-04) [i686-linux]
0: Open
0: Lock
0: Read
1: Open 
1: Lock
tmp/flock.rb:9:in `initialize': Interrupt
        from tmp/flock.rb:9:in `new'
        [...]

Thread #0's Read (f.gets) never returns, so Thread #1 cannot lock the
file.


Here is the script:

Filename = "/tmp/flock-test"
f = open(Filename, "w")
f.puts "foo"
f.close

2.times { |i|
    Thread.new {
	begin
	    loop do
		puts "#{i}: Open"
		f = open(Filename)
		puts "#{i}: Lock"
		f.flock(File::LOCK_EX)
		puts "#{i}: Read"
		puts "#{i}: " + f.gets
		#puts "#{i}: Unlock"
		#f.flock(File::LOCK_UN)
		puts "#{i}: Close"
		f.close
	    end
	rescue Exception => e
	    p e
	end
    }
}


Mike.
midulo.


On Fri, 22 Jun 2001 01:28:52 +0900
Michael Witrant <mike / lepton.fr> wrote:

> Hello,
> 
> I try to use File.flock to lock a file in a cgi script, but I can't
get
> it to work in my test script.
> It creates a file and write "foo". A thread that will write "bar" in
0.1
> secondes is started, and an infinite loop reads the file and print the
> result.
> The script displays some "foo" and waits, probably for the file to be
> unlocked. No "bar". I expected some "foo", then many "bar".
> 
> Here is the script:
> 
> filename = "/tmp/flock-test"
>     
> f = open(filename, "w")
> f.puts "foo"
> f.close
> 
> Thread.new {
>   sleep .1
>   f = open(filename, "w")
>   f.flock(File::LOCK_EX)
>   f.puts "bar"
>   f.flock(File::LOCK_UN)
>   f.close
> }
> 
> loop do
>   f = open(filename)
>   f.flock(File::LOCK_EX)
>   puts f.gets
>   f.flock(File::LOCK_UN)
>   f.close
> end
>     
> With the help of some puts, it seems to be blocking on f.gets in the
> main thread and f.flock in the writing thread.
> If I add "sleep .0001" in the main loop, it works.
> 
> Where am I wrong?
> 
> I tried to search "flock" on ruby-talk.com, but I got an Internal
Server
> Error.
> 
> 
> Mike.
> midulo.
>