Forum Moderators: coopster

Message Too Old, No Replies

Does flock always get released?

Early exits and file locking

         

trillianjedi

8:09 am on Jun 18, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I'm working on this (part of a basic logging function):-

$handle = fopen("access.log", "a");
flock($handle, LOCK_SH);
if (!$something) {exit; }
flock($handle, LOCK_UN);

The old C programmer in me sees the above code as bad. I'm not so sure about PHP though. I can't find anyway in PHP to do a try...finally type block, so I assume that PHP has this handled correctly and no matter what errors or early exits happen inside this file lock, the lock will always get released?

TJ

coopster

3:08 pm on Jun 19, 2006 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



I agree, the logic is not quite what you would like to see as a programmer. Also, I tend to tidy things up before an exit(). Or, don't even open the file in the first place if you don't need to.

As far as how PHP handles flock() [php.net] you will find that the manual page for this function states that PHP will automagically do the cleanup for you:


The lock is released also by fclose() [php.net] (which is also called automatically when script finished).

Still, I'm like you. I would tend to handle it a bit more cleanly in the code rather than rely on the engine to clean up after me.

trillianjedi

3:20 pm on Jun 19, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks Coop. I went to that very page before starting this thread, but for some reason I only see it in German (a language I don't speak) - wonder if I'm being mis-geo-targetted?

I would tend to handle it a bit more cleanly in the code rather than rely on the engine to clean up after me.

I agree - I prefer explicit coding every time. I don't like software trying to second guess what I want to do (even when I'm wrong lol).

At least it's good to know that PHP will close a file and release a lock when a script ends (and I assume that means "no matter how it ends").

Also, I tend to tidy things up before an exit().

That's one option I suppose, but, again, the old C programmer in me says "yuck!" when I see:-


$handle = fopen("access.log", "a");
flock($handle, LOCK_SH);
if (!$something) {
flock($handle, LOCK_UN);
fclose($handle);
exit;
}
fclose($handle);
flock($handle, LOCK_UN);

Bit ugly isn't it.

Or, don't even open the file in the first place if you don't need to.

That's a good design philosophy in general, and I do avoid that. My example is a poor one actually. I was thinking more of trapping errors - for example : if there's an error doing something with the file, drop the lock.

In the particular script I'm building, one of the objectives is to lock (well, queue) other Apache threads out of a sequence of events other than just the file procedures. So here I'm kind of cheating really by using a file lock as a means of creating a critical-section/mutex within PHP (as I couldn't find a mutex function existing in PHP).

I only want one thread running through this code at any given time, that's my concern over ensuring the lock is ultimately released and Apache threads are not just queued up behind it forever.

TJ

jatar_k

5:42 pm on Jun 19, 2006 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



>> no matter how it ends

I don't know about that one, I have seen some nasty examples of things not getting properly cleaned up when things die. file locks, db locks hanging there forever. I had to program a few cron cleanups to watch for things like that and fix them if it found them.

could you use syslog for something like this? though to be honest I read through this pretty quickly and am not 100% sure what you are doing.

coopster

5:51 pm on Jun 19, 2006 (gmt 0)

WebmasterWorld Administrator 10+ Year Member




Bit ugly isn't it.

Yes, but you could always throw it into a function and use it:

function flockUnlock($handle) 
{
flock($handle, LOCK_UN);
fclose($handle);
}
$handle = fopen("access.log", "a");
flock($handle, LOCK_SH);
if (!$something) {
flockUnlock($handle);
exit;
}
flockUnlock($handle);


as I couldn't find a mutex function existing in PHP

Semaphores [php.net]?

jatar_k

5:55 pm on Jun 19, 2006 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



that was the link I was looking for coop, nice

coopster

6:05 pm on Jun 19, 2006 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



Oh yeah, I was going to tell you ...


but for some reason I only see it in German (a language I don't speak) - wonder if I'm being mis-geo-targetted?

... the PHP site will set cookies and perhaps the cookie was set when you clicked a link on this site from which a user dropped a country-specific manual page link. I've had it happen to me once or twice ;)

Remove the cookie and you should get the pages in the default language once again.

trillianjedi

6:48 pm on Jun 19, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



am not 100% sure what you are doing.

Something that Apache wasn't designed to do ;)

I'm always doing that - but that's what being on the "bleeding edge" is all about, and these days running a website often depends on that...

Cookies

Deleted cookies, still getting it in German. I wonder if my IP block is stored in a DB somewhere as belonging to germany?

Semaphores

Ah, yes, why didn't I think of searching on that term! D'oh!

Thanks. That page is still in German for me, but I'll see if I've got something about it in my PHP book ;)

This kind of thing still concerns me a little in PHP though in the absence of a try...finally type block, particularly in light of Adams comments of having to revert to a CRON clean-up script.

TJ

jatar_k

6:50 pm on Jun 19, 2006 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



you should be able to follow the links through from

documentation > english

or just use the drop down that says "printer friendly" the other languages are under there

coopster

7:16 pm on Jun 19, 2006 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



tj, how about Exceptions [php.net]?

trillianjedi

7:39 pm on Jun 19, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



or just use the drop down that says "printer friendly" the other languages are under there

Double-D'oh! Mental note - RTFM!

Thanks ;)

Exceptions

I'm not sure how PHP handles this internally though - in C, the compiler would read this as "not critical, just an exception trap".

In a try..finally type block, the compiler would read it as "OK, whatever happens, before we do anything else this block of code must be executed.

I'll read up on it though. There's always a way around something in programming - I learned that a long time ago from a very good teacher.

TJ