A clone of btpd with my configuration changes.
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

105 рядки
2.1 KiB

  1. #include <time.h>
  2. #include "evloop.h"
  3. #include "timeheap.h"
  4. #if defined(CLOCK_MONOTONIC_FAST)
  5. #define TIMER_CLOCK CLOCK_MONOTONIC_FAST
  6. #elif defined(CLOCK_MONOTONIC)
  7. #define TIMER_CLOCK CLOCK_MONOTONIC
  8. #else
  9. #error CLOCK_MONOTONIC needed!
  10. #endif
  11. static struct timespec
  12. addtime(struct timespec a, struct timespec b)
  13. {
  14. struct timespec ret;
  15. ret.tv_sec = a.tv_sec + b.tv_sec;
  16. ret.tv_nsec = a.tv_nsec + b.tv_nsec;
  17. if (ret.tv_nsec >= 1000000000) {
  18. ret.tv_sec += 1;
  19. ret.tv_nsec -= 1000000000;
  20. }
  21. return ret;
  22. }
  23. static struct timespec
  24. subtime(struct timespec a, struct timespec b)
  25. {
  26. struct timespec ret;
  27. ret.tv_sec = a.tv_sec - b.tv_sec;
  28. ret.tv_nsec = a.tv_nsec - b.tv_nsec;
  29. if (ret.tv_nsec < 0) {
  30. ret.tv_sec -= 1;
  31. ret.tv_nsec += 1000000000;
  32. }
  33. return ret;
  34. }
  35. void
  36. timer_init(struct timeout *h, evloop_cb_t cb, void *arg)
  37. {
  38. h->cb = cb;
  39. h->arg = arg;
  40. h->th.i = -1;
  41. h->th.data = h;
  42. }
  43. int
  44. timer_add(struct timeout *h, struct timespec *t)
  45. {
  46. struct timespec now, sum;
  47. clock_gettime(TIMER_CLOCK, &now);
  48. sum = addtime(now, *t);
  49. if (h->th.i == -1)
  50. return timeheap_insert(&h->th, &sum);
  51. else {
  52. timeheap_change(&h->th, &sum);
  53. return 0;
  54. }
  55. }
  56. void
  57. timer_del(struct timeout *h)
  58. {
  59. if (h->th.i >= 0) {
  60. timeheap_remove(&h->th);
  61. h->th.i = -1;
  62. }
  63. }
  64. void
  65. timers_run(void)
  66. {
  67. struct timespec now;
  68. clock_gettime(TIMER_CLOCK, &now);
  69. while (timeheap_size() > 0) {
  70. struct timespec diff = subtime(timeheap_top(), now);
  71. if (diff.tv_sec < 0) {
  72. struct timeout *t = timeheap_remove_top();
  73. t->th.i = -1;
  74. t->cb(-1, EV_TIMEOUT, t->arg);
  75. } else
  76. break;
  77. }
  78. }
  79. struct timespec
  80. timer_delay(void)
  81. {
  82. struct timespec now, diff;
  83. if (timeheap_size() == 0) {
  84. diff.tv_sec = -1;
  85. diff.tv_nsec = 0;
  86. } else {
  87. clock_gettime(TIMER_CLOCK, &now);
  88. diff = subtime(timeheap_top(), now);
  89. if (diff.tv_sec < 0) {
  90. diff.tv_sec = 0;
  91. diff.tv_nsec = 0;
  92. }
  93. }
  94. return diff;
  95. }