Advanced Programming in the UNIX® Environment

(lily) #1
ptg10805159

490 Advanced I/O Chapter 14


struct flock lock;
lock.l_type = type; /* F_RDLCK or F_WRLCK */
lock.l_start = offset; /* byte offset, relative to l_whence */
lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
lock.l_len = len; /* #bytes (0 means to EOF) */
if (fcntl(fd, F_GETLK, &lock) < 0)
err_sys("fcntl error");
if (lock.l_type == F_UNLCK)
return(0); /* false, region isn’t locked by another proc */
return(lock.l_pid); /* true, return pid of lock owner */
}

Figure 14.6 Function to test for a locking condition

If a lock exists that would block the request specified by the arguments, this function
returns the process ID of the process holding the lock. Otherwise, the function returns 0
(false). Wenormally call this function from the following two macros (defined in
apue.h):

#define is_read_lockable(fd, offset, whence, len) \
(lock_test((fd), F_RDLCK, (offset), (whence), (len)) == 0)
#define is_write_lockable(fd, offset, whence, len) \
(lock_test((fd), F_WRLCK, (offset), (whence), (len)) == 0)

Note that thelock_testfunction can’t be used by a process to see whether it is
currently holding a portion of a file locked. The definition of theF_GETLKcommand
states that the information returned applies to an existing lock that would prevent us
from creating our own lock. Since theF_SETLKandF_SETLKWcommands always
replace a process’s existing lock if it exists, we can never block on our own lock; thus,
theF_GETLKcommand will never report our own lock.

Example — Deadlock


Deadlock occurs when two processes areeach waiting for a resource that the other has
locked. The potential for deadlock exists if a process that controls a locked region is put
to sleep when it tries to lock another region that is controlled by a different process.
Figure14.7 shows an example of deadlock. The child locks byte 0 and the parent
locks byte 1. Each then tries to lock the other’s already locked byte. We use the
parent–child synchronization routines from Section 8.9 (TELL_xxxandWAIT_xxx)so
that each process can wait for the other to obtain its lock.
#include "apue.h"
#include <fcntl.h>
static void
lockabyte(const char *name, int fd, off_t offset)
Free download pdf