eventfd.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #include <errno.h>
  2. #include <poll.h>
  3. #include <pthread.h>
  4. #include <signal.h>
  5. #include <stdint.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <stdarg.h>
  9. #include <string.h>
  10. #include <sys/eventfd.h>
  11. #include <sys/time.h>
  12. #include <sys/types.h>
  13. #include <unistd.h>
  14. #define MAX_EFDS 3
  15. int efds[MAX_EFDS] = { 0 };
  16. void* write_eventfd_thread(void* arg) {
  17. uint64_t count = 10;
  18. int* efds = (int*) arg;
  19. if (!arg) {
  20. printf("arg is NULL\n");
  21. return NULL;
  22. }
  23. printf("%s:got here\n", __func__);
  24. for (int i = 0; i < MAX_EFDS; i++) {
  25. printf("%s: efd = %d\n", __func__, efds[i]);
  26. }
  27. for (int i = 0; i < MAX_EFDS; i++) {
  28. sleep(1);
  29. write(efds[i], &count, sizeof(count));
  30. count += 1;
  31. }
  32. return NULL;
  33. }
  34. /* This function used to test polling on a group of eventfd descriptors.
  35. * To support regression testing, positive value returned for error case. */
  36. int eventfd_using_poll() {
  37. int ret = 0;
  38. struct pollfd pollfds[MAX_EFDS];
  39. pthread_t tid = 0;
  40. uint64_t count = 0;
  41. int poll_ret = 0;
  42. int nread_events = 0;
  43. for (int i = 0; i < MAX_EFDS; i++) {
  44. efds[i] = eventfd(0, 0);
  45. if (efds[i] < 0) {
  46. perror("eventfd failed");
  47. return 1;
  48. }
  49. printf("efd = %d\n", efds[i]);
  50. pollfds[i].fd = efds[i];
  51. pollfds[i].events = POLLIN;
  52. }
  53. ret = pthread_create(&tid, NULL, write_eventfd_thread, efds);
  54. if (ret != 0) {
  55. perror("error in thread creation\n");
  56. return 1;
  57. }
  58. while (1) {
  59. poll_ret = poll(pollfds, MAX_EFDS, 5000);
  60. if (poll_ret == 0) {
  61. printf("Poll timed out. Exiting.\n");
  62. break;
  63. }
  64. if (poll_ret < 0) {
  65. perror("error from poll");
  66. ret = 1;
  67. break;
  68. }
  69. for (int i = 0; i < MAX_EFDS; i++) {
  70. if (pollfds[i].revents & POLLIN) {
  71. pollfds[i].revents = 0;
  72. errno = 0;
  73. read(pollfds[i].fd, &count, sizeof(count));
  74. printf("fd set=%d\n", pollfds[i].fd);
  75. printf("efd = %d, count: %lu, errno=%d\n", pollfds[i].fd,
  76. count, errno);
  77. nread_events++;
  78. }
  79. }
  80. }
  81. if (nread_events == MAX_EFDS) {
  82. printf("%s completed successfully\n", __func__);
  83. } else
  84. printf("%s: nread_events=%d, MAX_EFDS=%d\n", __func__, nread_events, MAX_EFDS);
  85. pthread_join(tid, NULL);
  86. return ret;
  87. }
  88. /* This function used to test various flags supported while creating eventfd descriptors.
  89. * Note: EFD_SEMAPHORE has not been tested.
  90. * To support regression testing, positive value returned for error case. */
  91. int eventfd_using_various_flags() {
  92. uint64_t count = 0;
  93. int efd = 0;
  94. int eventfd_flags[] = { 0, EFD_NONBLOCK, EFD_CLOEXEC, EFD_NONBLOCK | EFD_CLOEXEC };
  95. for (int i = 0; i < sizeof(eventfd_flags) / sizeof(int); i++) {
  96. printf("iteration #-%d, flags=%d\n", i, eventfd_flags[i]);
  97. efd = eventfd(0, eventfd_flags[i]);
  98. if (efd < 0) {
  99. perror("eventfd failed");
  100. printf("eventfd error for iteration #-%d, flags-%d\n", i, eventfd_flags[i]);
  101. return 1;
  102. }
  103. count = 5;
  104. eventfd_write(efd, count);
  105. eventfd_write(efd, count);
  106. count = 0;
  107. errno = 0;
  108. eventfd_read(efd, &count);
  109. printf("efd = %d, count: %lu, errno=%d\n", efd, count, errno);
  110. /* calling the second read would block if flags doesn't have EFD_NONBLOCK */
  111. if (eventfd_flags[i] & EFD_NONBLOCK) {
  112. count = 0;
  113. errno = 0;
  114. eventfd_read(efd, &count);
  115. printf("efd = %d, count: %lu, errno=%d\n", efd, count, errno);
  116. }
  117. close(efd);
  118. }
  119. printf("%s completed successfully\n", __func__);
  120. return 0;
  121. }
  122. int main(int argc, char* argv[]) {
  123. int ret = 0;
  124. ret = eventfd_using_poll();
  125. ret += eventfd_using_various_flags();
  126. return ret;
  127. }