timer.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /**
  2. * This file client.c, handles clients of the WOE server.
  3. */
  4. #define _POSIX_C_SOURCE 200801L
  5. #define _POSIX_SOURCE 200801L
  6. #include <signal.h>
  7. #include <time.h>
  8. #include <errno.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <ctype.h>
  13. #include <math.h>
  14. #include "libtelnet.h"
  15. #include "monolog.h"
  16. #include "rh.h"
  17. #include "timer.h"
  18. #include "server.h"
  19. struct woe_timer * woe_timer_alloc() {
  20. return calloc(sizeof(struct woe_timer), 1);
  21. }
  22. struct woe_timer * woe_timer_init(struct woe_timer * me,
  23. struct woe_server * server, int index) {
  24. sigevent_t sev;
  25. if (!me) return NULL;
  26. me->server = server;
  27. me->index = index;
  28. me->set = 0;
  29. sev.sigev_notify= SIGEV_NONE;
  30. sev.sigev_notify = SIGEV_SIGNAL;
  31. sev.sigev_signo = SIGRTMIN + (index % (SIGRTMAX - SIGRTMIN - 1));
  32. sev.sigev_value.sival_ptr = me;
  33. if (timer_create(CLOCK_MONOTONIC, &sev, &me->timer) < 0) {
  34. LOG_ERROR("Could not create timer %d.", index);
  35. return NULL;
  36. }
  37. LOG_NOTE("Timer %d initialized: %d.\n", me->index, me->timer);
  38. return me;
  39. }
  40. struct woe_timer * woe_timer_new(struct woe_server * server, int index) {
  41. struct woe_timer * me = woe_timer_alloc();
  42. if (!me) return NULL;
  43. if (!woe_timer_init(me, server, index)) {
  44. free(me);
  45. return NULL;
  46. }
  47. return me;
  48. }
  49. struct woe_timer * woe_timer_done(struct woe_timer * me) {
  50. if (!me) return NULL;
  51. if (me->timer) timer_delete(me->timer);
  52. me->timer = NULL;
  53. LOG_NOTE("Timer %d destroyed.\n", me->index);
  54. me->index = -1;
  55. return me;
  56. }
  57. struct woe_timer * woe_timer_free(struct woe_timer * me) {
  58. woe_timer_done(me);
  59. free(me);
  60. return NULL;
  61. }
  62. struct timespec * timespec_init(struct timespec * tv, double sec) {
  63. if (!tv) return NULL;
  64. if (sec <= 0.0) {
  65. tv->tv_sec = 0;
  66. tv->tv_nsec = 0;
  67. } else {
  68. tv->tv_sec = floor(sec);
  69. tv->tv_nsec = (sec - floor(sec)) * 1000000000;
  70. }
  71. return tv;
  72. }
  73. double timespec_to_s(struct timespec * tv) {
  74. return tv->tv_sec + ( tv->tv_nsec / 1000000000.0 );
  75. }
  76. int woe_timer_get(struct woe_timer * me, double * value, double * interval) {
  77. int res;
  78. if (!me) return -1;
  79. struct itimerspec get;
  80. /* timespec_init(&nv.it_value, value); */
  81. res = timer_gettime(me->timer, &get);
  82. if (res == 0) {
  83. if (value) (*value) = timespec_to_s(&get.it_value);
  84. if (interval) (*interval) = timespec_to_s(&get.it_interval);
  85. }
  86. return res;
  87. }
  88. int woe_timer_set(struct woe_timer * me, double value, double interval) {
  89. if (!me) return -1;
  90. me->set = 1;
  91. struct itimerspec nv, ov;
  92. timespec_init(&nv.it_value, value);
  93. timespec_init(&nv.it_interval, interval);
  94. return timer_settime(me->timer, 0, &nv, &ov);
  95. }
  96. int woe_timer_passed(struct woe_timer * me) {
  97. double value, interval;
  98. if (!me) return 0;
  99. if (!me->set) return 0;
  100. if (woe_timer_get(me, &value, &interval) != 0) {
  101. LOG_ERROR("Trouble getting timer %d\n", me->index);
  102. return 0;
  103. }
  104. return value <= 0;
  105. }
  106. int woe_timer_callback(struct woe_timer * me) {
  107. mrb_state * mrb;
  108. LOG_DEBUG("Timer passed: %d\n", me->index);
  109. mrb = woe_server_get_mrb(me->server);
  110. if (mrb) {
  111. double value = 0.0, interval = 0.0;
  112. woe_timer_get(me, &value, &interval);
  113. rh_run_toplevel(mrb, "woe_on_timer", "iff", me->index, value, interval);
  114. }
  115. return 0;
  116. }