21.03.2013 Views

Problem - Kevin Tafuro

Problem - Kevin Tafuro

Problem - Kevin Tafuro

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

int spc_lock_file(const char *lfpath) {<br />

int attempt, fd, result;<br />

pid_t pid;<br />

/* Try three times, if we fail that many times, we lose */<br />

for (attempt = 0; attempt < 3; attempt++) {<br />

if ((fd = open(lfpath, O_RDWR | O_CREAT | O_EXCL, S_IRWXU)) = = -1) {<br />

if (errno != EEXIST) return -1;<br />

if ((fd = open(lfpath, O_RDONLY)) = = -1) return -1;<br />

result = read_data(fd, &pid, sizeof(pid));<br />

close(fd);<br />

if (result) {<br />

if (pid = = getpid( )) return 1;<br />

if (kill(pid, 0) = = -1) {<br />

if (errno != ESRCH) return -1;<br />

attempt--;<br />

unlink(lfpath);<br />

continue;<br />

}<br />

}<br />

sleep(1);<br />

continue;<br />

}<br />

pid = getpid( );<br />

if (!write_data(fd, &pid, sizeof(pid))) {<br />

close(fd);<br />

return -1;<br />

}<br />

close(fd);<br />

attempt--;<br />

}<br />

/* If we've made it to here, three attempts have been made and the lock could<br />

* not be obtained. Return an error code indicating failure to obtain the<br />

* requested lock.<br />

*/<br />

return 0;<br />

}<br />

The first step in attempting to obtain the lock is to try to create the lock file. If this<br />

succeeds, the caller’s process ID is written to the file, the file is closed, and the loop is<br />

executed again. The loop counter is decremented first to ensure that at least one<br />

more iteration will always occur. The next time through the loop, creating the file<br />

should fail but won’t necessarily do so, because another process was attempting to<br />

get the lock at the same time from a stale process and deleted the lock file out from<br />

under this process. If this happens, the whole process begins again.<br />

If the lock file cannot be created, the lock file is opened for reading, and the ID of the<br />

process holding the lock is read from the file. The read is blocking, so if another process<br />

has begun to write out its ID, the read will block until the other process is done.<br />

Another race condition here could be avoided by performing a non-blocking read in<br />

62 | Chapter 2: Access Control<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!