Page 1 of 1

Do I need some kind of semaphore for my file access?

Posted: Thu Jul 15, 2004 2:17 pm
by tvink
I am writing my first non-trivial php application. I have a file where user entered data ( from a form) is kept.

When the form is submitted, my data file is read into an array. The array is updated from the form data, and then the file is overwritten with new contents. Then the next browser page is echoed out.

Since this all happens in one execution of my php script do I have to worry about multiple users stepping on each other? ... or will the server OS and web server handle this? ( I guess I am asking... can the execution of one php script be preempted by another? )

( for example, user a reads the file, then user b reads the file, then user b updates the file, then user a updates the file... loosing user b's data.)


Thanks in advance,
Tony

Posted: Thu Jul 15, 2004 2:27 pm
by feyd
yes, you need a semaphore.

Posted: Thu Jul 15, 2004 3:56 pm
by tvink
Thanks.

Looking through the PHP file system functions, it looks like flock() is the function that I would use. I would acquire an exclusive lock before reading the file and release it after writing the updated version.

What would other php threads see when they attempt to acquire an exclusive lock when the file is already locked? Would they just be held off until the lock was released? Would the flock() return flalse?

The PHP doco is a bit unclear about that.

Thanks,
Tony

Posted: Thu Jul 15, 2004 4:01 pm
by feyd
the lock should fail, or something like that..

Posted: Thu Jul 15, 2004 4:12 pm
by tvink
Bummer!

Being defensive, I probably need to start some kind of timer to avoid getting stuck if the flock() never returns true.

Any idea how long of a timeout would make sense?


Tony

Posted: Thu Jul 15, 2004 4:21 pm
by feyd
it should take more than a second to read the content, adjust some values, and dump it back out for most machines..

Posted: Thu Jul 15, 2004 7:38 pm
by Buddha443556
flock() isn't perfect in PHP and is dependent on the operating system being used.

open check out the x and x+ flags (php >= 4.3.2).
Man Page - open (2)
rename is atomic on linux os.
Man Page - rename

Posted: Fri Jul 16, 2004 8:21 am
by tvink
Thanks for the tip...

If I get what your are saying...

I would create a file to be used as a lock flag, name it lock.txt or something. This would be used to lock the data file.

The thread attempting to access the data file would first attempt to open lock.txt. with the X+ flag.

If it succedes, it would be the owner of the data file.

If some other thread already created lock.txt, our thread would be blocked until the file was deleted... and then it would unblock and procedd automatically.

When our thread finishes with the data file, the thread would delete lock.txt


Please answer a couple of questions because this is going to be really tough to test so I want to get the concept right.

1) Why did you reference "rename"? I can't think of a way to use this in a scheme like this? I must be missing something.

2) The linux open commands that you reference appear to block since there is a flag that makes it non-blocking. However I don't see how this applies to php since the open command is documented as returning a pass/fail status.

Anyway, the approach looks interesting but I am still a little confused. Any help is appreciated.

Thanks,
Tony

Posted: Fri Jul 16, 2004 9:34 am
by Buddha443556
tvink wrote:Thanks for the tip...

If I get what your are saying...

I would create a file to be used as a lock flag, name it lock.txt or something. This would be used to lock the data file.

The thread attempting to access the data file would first attempt to open lock.txt. with the X+ flag.

If it succedes, it would be the owner of the data file.

If some other thread already created lock.txt, our thread would be blocked until the file was deleted... and then it would unblock and procedd automatically.

When our thread finishes with the data file, the thread would delete lock.txt
Sounds good but I'm no expert. With MySQL so widely available I have the feeling the file system functions have been rather neglected in PHP. fopen() did not have an excl flag till version 4.3.2 as a case in point. flock() was pretty useless till then.
tvink wrote: 1) Why did you reference "rename"? I can't think of a way to use this in a scheme like this? I must be missing something.
To use rename you would create a temporary file and rename it to replace the original file. Since it's an atomic operation under Linux it's a somewhat safe way to update active files. Comes in handy for versions of PHP < 4.3.2.
tvink wrote: 2) The linux open commands that you reference appear to block since there is a flag that makes it non-blocking. However I don't see how this applies to php since the open command is documented as returning a pass/fail status.
When you use the x flags with PHP it's Open(2) system command being used. It was for reference - knowing it's limitations might help.

I would also recommend reviewing the available content caching systems such as Cache Lite. These system face many of the same problems as those discussed here.

Posted: Fri Jul 16, 2004 9:37 am
by tvink
Thanks!