/*********************************************************************** * This is a STC to show that flock occasionally does not work. * * It tries to use flock() for file locking. It creates a temporary * file, the uses fork to spawn a number of children. Each child opens * the file, then repeatedly uses flock to lock and unlock it. * * While each child has the lock, it increments a counter stored in * shared memory in a racy way, passing the current value to a function * which sleeps briefly, then returns the incremented counter. * * If all works correctly, the counter should end up be incremented * by each child iteration. * * However, this is failing for me occasionally. The counter ends up * being less than the expected value. * * This test was extracted from the APR test suite. * * Compile: gcc -Wall -o stc-flock-fork stc-flock-fork.c ***********************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #define MAX_ITER 200 #define CHILDREN 6 #define MAX_COUNT (MAX_ITER * CHILDREN) /* Counter stored in shared memory. */ static volatile int *x; /* A temporary file used for flock. */ char tmpfilename[] = "/tmp/flocktstXXXXXX"; /* a slower more racy way to implement (*x)++ */ static int increment(int n) { usleep(1); return n+1; } /* Fork and use flock to lock and unlock the file repeatedly in the child. */ void make_child(int trylock, pid_t *pid) { if ((*pid = fork()) < 0) { perror("fork failed"); exit(1); } else if (*pid == 0) { int fd2 = open(tmpfilename, O_RDONLY); if (fd2 < 0) { perror("child open"); exit(1); } int rc; int i; for (i=0; i