ofdlocks.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /* Open File Description Locks Usage Example
  2. Copyright (C) 1991-2019 Free Software Foundation, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #define _GNU_SOURCE
  15. #include <stdio.h>
  16. #include <sys/types.h>
  17. #include <sys/stat.h>
  18. #include <unistd.h>
  19. #include <fcntl.h>
  20. #include <pthread.h>
  21. #define FILENAME "/tmp/foo"
  22. #define NUM_THREADS 3
  23. #define ITERATIONS 5
  24. void *
  25. thread_start (void *arg)
  26. {
  27. int i, fd, len;
  28. long tid = (long) arg;
  29. char buf[256];
  30. struct flock lck = {
  31. .l_whence = SEEK_SET,
  32. .l_start = 0,
  33. .l_len = 1,
  34. };
  35. fd = open ("/tmp/foo", O_RDWR | O_CREAT, 0666);
  36. for (i = 0; i < ITERATIONS; i++)
  37. {
  38. lck.l_type = F_WRLCK;
  39. fcntl (fd, F_OFD_SETLKW, &lck);
  40. len = sprintf (buf, "%d: tid=%ld fd=%d\n", i, tid, fd);
  41. lseek (fd, 0, SEEK_END);
  42. write (fd, buf, len);
  43. fsync (fd);
  44. lck.l_type = F_UNLCK;
  45. fcntl (fd, F_OFD_SETLK, &lck);
  46. /* sleep to ensure lock is yielded to another thread */
  47. usleep (1);
  48. }
  49. pthread_exit (NULL);
  50. }
  51. int
  52. main (int argc, char **argv)
  53. {
  54. long i;
  55. pthread_t threads[NUM_THREADS];
  56. truncate (FILENAME, 0);
  57. for (i = 0; i < NUM_THREADS; i++)
  58. pthread_create (&threads[i], NULL, thread_start, (void *) i);
  59. pthread_exit (NULL);
  60. return 0;
  61. }