File lock annoying behaviour: bug or OK?

Tim Smith (tzs@tzs.net)
Sun, 16 May 1999 16:39:38 -0700 (PDT)


Consider the pair of programs at the end of this message. "producer" creates
a file in append mode, and loops writing lines to it. It locks the file for
each write, and unlocks it afterwards, and then immediately locks it again in
anticipation of the next write. "consumer" locks the file, prints its
contents, and then truncates it. "Producer" has a 3 second sleep while
holding the lock, to make sure that "consumer" will be very likely to
go to sleep waiting for the lock.

On my system (Linux 2.2.9), if I do this:

./producer foo &
./consumer foo

the "consumer" program never gets the file lock. Is this a bug in file
locking, or is this one of those annoying places where the applicable
standards don't actually specify what happens?

For comparison, on FreeBSD 3.1 (under VMWare on Linux), it works like I want
it to: unlocking the file in "producer" causes "consumer" to get the lock.

--Tim Smith

---------------- producer -------------------
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#include <fcntl.h>
#include <unistd.h>

int lock( int fd, int whence, off_t start, off_t len );
int unlock( int fd, int whence, off_t start, off_t len );

int main( int argc, char *argv[] )
{
int fd = open( argv[1], O_RDWR | O_CREAT | O_APPEND, 0666 );
while ( 1 ) {
lock( fd, SEEK_SET, 0, 1 );
write( fd, "foo\n", 4 );
sleep(3);
unlock( fd, SEEK_SET, 0, 1 );
}
return 0;
}

int lock( int fd, int whence, off_t start, off_t len )
{
struct flock l;

l.l_type = F_WRLCK;
l.l_whence = whence;
l.l_start = start;
l.l_len = len;
return fcntl( fd, F_SETLKW, &l );
}

int unlock( int fd, int whence, off_t start, off_t len )
{
struct flock l;

l.l_type = F_UNLCK;
l.l_whence = whence;
l.l_start = start;
l.l_len = len;
return fcntl( fd, F_SETLK, &l );
}
---------------- consumer -------------------
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#include <fcntl.h>
#include <unistd.h>

int lock( int fd, int whence, off_t start, off_t len );

int lock( int fd, int whence, off_t start, off_t len )
{
struct flock l;

l.l_type = F_WRLCK;
l.l_whence = whence;
l.l_start = start;
l.l_len = len;
return fcntl( fd, F_SETLKW, &l );
}

int main( int argc, char *argv[] )
{
int fd = open( argv[1], O_RDWR );
char buf[512];
int got;
lock( fd, SEEK_SET, 0, 1 );
while ( (got = read( fd, buf, sizeof buf )) > 0 )
write( 1, buf, got );
ftruncate( fd, 0 );
return 0;
}
--------------------------------------------

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/