0

I am using flock to prevent concurrent access to a shared resource. It works fine the first time I check the lock, but the second time I check the lock, I am able to successfully obtain it despite the fact that lock is stil being held by another process.

I am using the following code:

#include <stdio.h>
#include <sys/file.h>
#include <errno.h>
int main(void) {

 printf("App started:\n");

 int fd = open("test.lock", O_RDWR | O_CREAT, 0666); // open or create   lockfile
 //check open success...
 int rc = flock(fd, LOCK_EX | LOCK_NB); // grab exclusive lock, fail if   can't obtain.
 if (rc)
 {
    printf("Failed .. lock is already held\n");
    if(EWOULDBLOCK == errno)
    {
      printf("errno said, that we would block\n");
    }
    return 0;
 }
 else
 {
   printf("Lock obtained\n");
 }

 printf("Press ENTER...\n");
 getc(stdin);
 return 0;
}

Platform: OSX 10.10.

If I run the program in two separate terminal windows, I get the following output:

First window - the app acquires the lock and waits for key to be pressed

App started: Lock obtained Press ENTER...

Second terminal window first run - application sucesfully finds out, that the lock is already held by someone else

App started: Failed .. lock is already held errno said, that we would block

Second terminal window second run - application obtains the lock despite the fact that first instance is already holding it

App started: Lock obtained Press ENTER...

It as if testing for lock would also release it...

Any ideas?

UPDATE: This looks like OS X related problem. The code works without problem on 14.04 32 bit. Matra

matra
  • 9,763
  • 4
  • 20
  • 31
  • This appears to be C code. Any **valid** reason you added the C++ tag? – too honest for this site Nov 16 '15 at 16:08
  • Check for errors. And release the lock! – too honest for this site Nov 16 '15 at 16:09
  • this code block: ` printf("Failed .. lock is already held\n"); if(EWOULDBLOCK == errno) { printf("errno said, that we would block\n"); }` can be simplified to one line: `perrof( 'flock failed");` as that would print the enclosed text plus the appropriate system error message. Then no need for the statement: `#include ` – user3629249 Nov 16 '15 at 17:38
  • 1
    I ran the code in a terminal window, and let it sit waiting for a user keystroke. Then in a second terminal window I ran the code over and over and over. it always output: `App started: Failed .. lock is already held errno said, that we would block` I.E. on my system, ubuntu linux 14.04, it always works correctly – user3629249 Nov 16 '15 at 17:48
  • Thanks, I also get it working on Ubuntu.l It looks like this is an OS X specific problem. I've updated the question – matra Nov 16 '15 at 22:34

1 Answers1

0

It turned out that the problem on OS X was that program was run from network mounted directory (windows share). Locks do not work reliably on NFS. See https://stackoverflow.com/a/22411531/174638 for details.

Community
  • 1
  • 1
matra
  • 9,763
  • 4
  • 20
  • 31