1132 Chapter 55
We start a first instance (process A) of the program in Listing 55-2, placing a
read lock on bytes 0 to 39 of the file:
Terminal window 1
$ ls -l tfile
-rw-r--r-- 1 mtk users 100 Apr 18 12:19 tfile
$ ./i_fcntl_locking tfile
Enter? for help
PID=790> s r 0 40
[PID=790] got lock
Then we start a second instance of the program (process B), placing a read lock on
a bytes 70 through to the end of the file:
Terminal window 2
$ ./i_fcntl_locking tfile
Enter? for help
PID=800> s r -30 0 e
[PID=800] got lock
At this point, things appear as shown in part a of Figure 55-5, where process A (pro-
cess ID 790) and process B (process ID 800) hold locks on different parts of the file.
Now we return to process A, where we try to place a write lock on the entire
file. We first employ F_GETLK to test whether the lock can be placed and are
informed that there is a conflicting lock. Then we try placing the lock with F_SETLK,
which also fails. Finally, we try placing the lock with F_SETLKW, which blocks.
PID=790> g w 0 0
[PID=790] Denied by READ lock on 70:0 (held by PID 800)
PID=790> s w 0 0
[PID=790] failed (incompatible lock)
PID=790> w w 0 0
At this point, things appear as shown in part b of Figure 55-5, where process A and
process B each hold a lock on different parts of the file, and process A has a
queued lock request on the whole file.
We continue in process B, by trying to place a write lock on the entire file. We
first test whether the lock can be placed using F_GETLK, which informs us that there
is a conflicting lock. We then try placing the lock using F_SETLKW.
PID=800> g w 0 0
[PID=800] Denied by READ lock on 0:40
(held by PID 790)
PID=800> w w 0 0
[PID=800] failed (deadlock)
Part c of Figure 55-5 shows what happened when process B made a blocking
request to place a write lock on the entire file: a deadlock. At this point, the kernel
selected one of the lock requests to fail—in this case, the request by process B,
which then receives the EDEADLK error from its fcntl() call.
We continue in process B, by removing all of its locks on the file:
PID=800> s u 0 0
[PID=800] unlocked
[PID=790] got lock