php - Difference between return value of non-blocking flock function and the $wouldblock argument? -


i'm trying understand non blocking flock , wouldblock argument

$fp = fopen('/tmp/lock.txt', 'r+');  if(flock($fp, lock_ex | lock_nb, $wouldblock)) {   echo 'lock obtained'; } else{   echo 'unable obtain lock'; } fclose($fp); 

documentation says wouldblock:

the optional third argument set 1 if lock block (ewouldblock errno condition).

reproducing in test enviroment concurrent condition, if process has gained lock, flock function immeditatly return false (non blocking)

so why should care $wouldblock value if return value of flock function in non-blocking mode allready tells me lock couldn't obtained?

i can't difference between flock function returning false , $wouldblock argument setted 1, , $wouldblock argument usefull for.

this because flock() may fail not because lock gained somewhere else. in such case wouldn't block waiting lock being released, return false. in other words lock_nb if flock returns false , wouldblock=1 means, tried gain lock acquired somewhere else. if flock lock_nb returns false , wouldblock=0 means bad happen , flock didn't consider waiting gain lock impossible.

check out code(here gist):

<?php // let's create /tmp/ninja-lock1.txt ... $fp0 = fopen('/tmp/ninja-lock1.txt', 'c'); // ... , close imiedietly fclose($fp0);  // file handler $fp0 closed flock() // unable use gain lock. // fail wouldblock set 0 // doesn't make sense wait on unusable file handle. // // btw flock() throws in such case warning "x not valid stream resource". // purpose of clear output example // i've suppressed @ - don't use @ in production $flockresult = @flock($fp0, lock_ex | lock_nb, $wouldblock); printf("flock=%b; wouldblock=%d (acquire lock: %s)\n", $flockresult, $wouldblock, "failure, broken file handle");  // 2 handlers /tmp/ninja-lock2.txt // show flock() blocking result. $fp1 = fopen('/tmp/ninja-lock2.txt', 'c'); $fp2 = fopen('/tmp/ninja-lock2.txt', 'c');   // nobody locking on /tmp/ninja-lock2.txt, // acquire lock , wouldblock 0 $flockresult = flock($fp1, lock_ex | lock_nb, $wouldblock); printf("flock=%b; wouldblock=%d (acquire lock: %s)\n", $flockresult, $wouldblock, "success");  // file locked on $fp1 handle flock won't acquire lock // , wouldblock 1 $flockresult = flock($fp2, lock_ex | lock_nb, $wouldblock); printf("flock=%b; wouldblock=%d (acquire lock: %s)\n", $flockresult, $wouldblock, "failure, acquired somewhere else");  // result: // $ php flock.php  // flock=0; wouldblock=0 (acquire lock: failure, broken file handle) // flock=1; wouldblock=0 (acquire lock: success) // flock=0; wouldblock=1 (acquire lock: failure, acquired somewhere else) ?> 

also clear confusion of future readers it's worth note checking ewouldblock makes sense flock() lock_nb flag, in blocking mode it's either success , block or failure , no block.

you can confirm looking php source code flock:

phpapi int php_flock(int fd, int operation) #if have_struct_flock /* {{{ */ {     struct flock flck;     int ret;      flck.l_start = flck.l_len = 0;     flck.l_whence = seek_set;      if (operation & lock_sh)         flck.l_type = f_rdlck;     else if (operation & lock_ex)         flck.l_type = f_wrlck;     else if (operation & lock_un)         flck.l_type = f_unlck;     else {         errno = einval;         return -1;     }      ret = fcntl(fd, operation & lock_nb ? f_setlk : f_setlkw, &flck);      if (operation & lock_nb && ret == -1 &&              (errno == eacces || errno == eagain))         errno = ewouldblock;      if (ret != -1) ret = 0;      return ret; } 

ewouldblock set if operation & lock_nb && ret == -1 && (errno == eacces || errno == eagain).

if more interested in implementation can read man page of fcntl, parts f_setlk , f_setlkw:

f_setlk

acquire lock (when l_type f_rdlck or f_wrlck) or release lock (when l_type f_unlck) on bytes specified l_whence, l_start, , l_len fields of lock. if conflicting lock held process, call returns -1 , sets errno eacces or eagain.

f_setlkw

as f_setlk, if conflicting lock held on file, wait lock released. if signal caught while waiting, call interrupted , (after signal handler has returned) returns (with return value -1 , errno set eintr).


Comments

Popular posts from this blog

google api - Incomplete response from Gmail API threads.list -

Installing Android SQLite Asset Helper -

Qt Creator - Searching files with Locator including folder -