Question

From my old-school developper POV, doing this is strange:

$f = fopen($this->_fileName, "r");
if ($f===false) {
    throw new Exception("bla");
}
$locked = flock($f, LOCK_SH);
if (!$locked) {
    throw new Exception("bla");
}
$content = file_get_contents($this->_fileName);
flock($f, LOCK_UN);
fclose($f);

Or doing something like:

$f = fopen($this->_fileName, "r");
if ($f===false) {
    throw new Exception("bla");
}
$locked = flock($f, LOCK_SH);
if (!$locked) {
    throw new Exception("bla");
}
$content = fread($f, filesize($this->_fileName));
flock($f, LOCK_UN);
fclose($f);

i.e. if I'm opening with fopen(), I should use $f all the time. But in my two samples, two functions dont use the $f and I'm sure they try to open the file to read some information in it: file_get_contents() and filesize().

I could do a loop:

$content = ''; 
while(!feof($f)) 
    $content .= fread($f, 4096); 
flock($f, LOCK_UN);
fclose($f);

But I remember that I've read some time ago that this loop is much slower than the two solutions I'm suggesting. What is the safest and the most effective way of doing this (safest comes first)?

Was it helpful?

Solution

Yes. All code accessing the shared resource (in this case $this->fileName) simply needs to agree to lock something, not necessarily the shared resource.

For example (pseudo-code):

$lock = flock('/tmp/lockfile'); 
file_put_contents('/etc/foo.ini', 'whatever');
funlock($lock);

Notice the thing I'm locking is not the same thing I'm overwriting.

However, traditionally flock is applied to the file handle for the shared file, simply because it's easier than opening another handle just for a lock file (and saves the memory allocation of said opening). There's no requirement for that, though, just programmer ease.

In general, flock is a means to provide a cooperative, advisory, read-write locking mechanism on top of the file system: it doesn't actually do anything to the thing being locked.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top