You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

libev_helper.c 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * Copyright 2024 Vsevolod Stakhov
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "libev_helper.h"
  17. static void
  18. rspamd_ev_watcher_io_cb(EV_P_ struct ev_io *w, int revents)
  19. {
  20. struct rspamd_io_ev *ev = (struct rspamd_io_ev *) w->data;
  21. ev->cb(ev->io.fd, revents, ev->ud);
  22. }
  23. static void
  24. rspamd_ev_watcher_timer_cb(EV_P_ struct ev_timer *w, int revents)
  25. {
  26. struct rspamd_io_ev *ev = (struct rspamd_io_ev *) w->data;
  27. /*
  28. * We now call timeout callback in all the cases, as we assume that all
  29. * timeouts are final
  30. */
  31. ev->cb(ev->io.fd, EV_TIMER, ev->ud);
  32. }
  33. void rspamd_ev_watcher_init(struct rspamd_io_ev *ev,
  34. int fd,
  35. short what,
  36. rspamd_ev_cb cb,
  37. void *ud)
  38. {
  39. ev_io_init(&ev->io, rspamd_ev_watcher_io_cb, fd, what);
  40. ev->io.data = ev;
  41. ev_init(&ev->tm, rspamd_ev_watcher_timer_cb);
  42. ev->tm.data = ev;
  43. ev->ud = ud;
  44. ev->cb = cb;
  45. }
  46. void rspamd_ev_watcher_start(struct ev_loop *loop,
  47. struct rspamd_io_ev *ev,
  48. ev_tstamp timeout)
  49. {
  50. g_assert(ev->cb != NULL);
  51. ev_io_start(EV_A, &ev->io);
  52. if (timeout > 0) {
  53. /* Update timestamp to avoid timers running early */
  54. ev_now_update_if_cheap(loop);
  55. ev->timeout = timeout;
  56. ev_timer_set(&ev->tm, timeout, 0.0);
  57. ev_timer_start(EV_A, &ev->tm);
  58. }
  59. }
  60. void rspamd_ev_watcher_stop(struct ev_loop *loop,
  61. struct rspamd_io_ev *ev)
  62. {
  63. if (ev_can_stop(&ev->io)) {
  64. ev_io_stop(EV_A, &ev->io);
  65. }
  66. if (ev->timeout > 0) {
  67. ev_timer_stop(EV_A, &ev->tm);
  68. }
  69. }
  70. void rspamd_ev_watcher_reschedule(struct ev_loop *loop,
  71. struct rspamd_io_ev *ev,
  72. short what)
  73. {
  74. g_assert(ev->cb != NULL);
  75. if (ev_can_stop(&ev->io)) {
  76. ev_io_stop(EV_A, &ev->io);
  77. ev_io_set(&ev->io, ev->io.fd, what);
  78. ev_io_start(EV_A, &ev->io);
  79. }
  80. else {
  81. ev->io.data = ev;
  82. ev_io_init(&ev->io, rspamd_ev_watcher_io_cb, ev->io.fd, what);
  83. ev_io_start(EV_A, &ev->io);
  84. }
  85. if (ev->timeout > 0) {
  86. if (!(ev_can_stop(&ev->tm))) {
  87. /* Update timestamp to avoid timers running early */
  88. ev_now_update_if_cheap(loop);
  89. ev->tm.data = ev;
  90. ev_timer_init(&ev->tm, rspamd_ev_watcher_timer_cb, ev->timeout, 0.0);
  91. ev_timer_start(EV_A, &ev->tm);
  92. }
  93. }
  94. }
  95. void rspamd_ev_watcher_reschedule_at(struct ev_loop *loop,
  96. struct rspamd_io_ev *ev,
  97. short what,
  98. ev_tstamp at)
  99. {
  100. g_assert(ev->cb != NULL);
  101. if (ev_can_stop(&ev->io)) {
  102. ev_io_stop(EV_A, &ev->io);
  103. ev_io_set(&ev->io, ev->io.fd, what);
  104. ev_io_start(EV_A, &ev->io);
  105. }
  106. else {
  107. ev->io.data = ev;
  108. ev_io_init(&ev->io, rspamd_ev_watcher_io_cb, ev->io.fd, what);
  109. ev_io_start(EV_A, &ev->io);
  110. }
  111. if (at > 0) {
  112. if (!(ev_can_stop(&ev->tm))) {
  113. /* Update timestamp to avoid timers running early */
  114. ev_now_update_if_cheap(loop);
  115. ev->tm.data = ev;
  116. ev_timer_init(&ev->tm, rspamd_ev_watcher_timer_cb, at, 0.0);
  117. ev_timer_start(EV_A, &ev->tm);
  118. }
  119. }
  120. }