event_notifier-posix.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. * event notifier support
  3. *
  4. * Copyright Red Hat, Inc. 2010
  5. *
  6. * Authors:
  7. * Michael S. Tsirkin <mst@redhat.com>
  8. *
  9. * This work is licensed under the terms of the GNU GPL, version 2 or later.
  10. * See the COPYING file in the top-level directory.
  11. */
  12. #include "qemu/osdep.h"
  13. #include "qemu-common.h"
  14. #include "qemu/cutils.h"
  15. #include "qemu/event_notifier.h"
  16. #include "qemu/main-loop.h"
  17. #ifdef CONFIG_EVENTFD
  18. #include <sys/eventfd.h>
  19. #endif
  20. #ifdef CONFIG_EVENTFD
  21. /*
  22. * Initialize @e with existing file descriptor @fd.
  23. * @fd must be a genuine eventfd object, emulation with pipe won't do.
  24. */
  25. void event_notifier_init_fd(EventNotifier *e, int fd)
  26. {
  27. e->rfd = fd;
  28. e->wfd = fd;
  29. }
  30. #endif
  31. int event_notifier_init(EventNotifier *e, int active)
  32. {
  33. int fds[2];
  34. int ret;
  35. #ifdef CONFIG_EVENTFD
  36. ret = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
  37. #else
  38. ret = -1;
  39. errno = ENOSYS;
  40. #endif
  41. if (ret >= 0) {
  42. e->rfd = e->wfd = ret;
  43. } else {
  44. if (errno != ENOSYS) {
  45. return -errno;
  46. }
  47. if (qemu_pipe(fds) < 0) {
  48. return -errno;
  49. }
  50. ret = fcntl_setfl(fds[0], O_NONBLOCK);
  51. if (ret < 0) {
  52. ret = -errno;
  53. goto fail;
  54. }
  55. ret = fcntl_setfl(fds[1], O_NONBLOCK);
  56. if (ret < 0) {
  57. ret = -errno;
  58. goto fail;
  59. }
  60. e->rfd = fds[0];
  61. e->wfd = fds[1];
  62. }
  63. if (active) {
  64. event_notifier_set(e);
  65. }
  66. return 0;
  67. fail:
  68. close(fds[0]);
  69. close(fds[1]);
  70. return ret;
  71. }
  72. void event_notifier_cleanup(EventNotifier *e)
  73. {
  74. if (e->rfd != e->wfd) {
  75. close(e->rfd);
  76. }
  77. e->rfd = -1;
  78. close(e->wfd);
  79. e->wfd = -1;
  80. }
  81. int event_notifier_get_fd(const EventNotifier *e)
  82. {
  83. return e->rfd;
  84. }
  85. int event_notifier_set(EventNotifier *e)
  86. {
  87. static const uint64_t value = 1;
  88. ssize_t ret;
  89. do {
  90. ret = write(e->wfd, &value, sizeof(value));
  91. } while (ret < 0 && errno == EINTR);
  92. /* EAGAIN is fine, a read must be pending. */
  93. if (ret < 0 && errno != EAGAIN) {
  94. return -errno;
  95. }
  96. return 0;
  97. }
  98. int event_notifier_test_and_clear(EventNotifier *e)
  99. {
  100. int value;
  101. ssize_t len;
  102. char buffer[512];
  103. /* Drain the notify pipe. For eventfd, only 8 bytes will be read. */
  104. value = 0;
  105. do {
  106. len = read(e->rfd, buffer, sizeof(buffer));
  107. value |= (len > 0);
  108. } while ((len == -1 && errno == EINTR) || len == sizeof(buffer));
  109. return value;
  110. }