rq.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /* $OpenLDAP$ */
  2. /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  3. *
  4. * Copyright 2003-2022 The OpenLDAP Foundation.
  5. * Portions Copyright 2003 IBM Corporation.
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted only as authorized by the OpenLDAP
  10. * Public License.
  11. *
  12. * A copy of this license is available in file LICENSE in the
  13. * top-level directory of the distribution or, alternatively, at
  14. * <http://www.OpenLDAP.org/license.html>.
  15. */
  16. /* This work was initially developed by Jong Hyuk Choi for inclusion
  17. * in OpenLDAP Software.
  18. */
  19. #include "portable.h"
  20. #include <stdio.h>
  21. #include <ac/stdarg.h>
  22. #include <ac/stdlib.h>
  23. #include <ac/errno.h>
  24. #include <ac/socket.h>
  25. #include <ac/string.h>
  26. #include <ac/time.h>
  27. #include "ldap-int.h"
  28. #ifdef LDAP_R_COMPILE
  29. #include "ldap_pvt_thread.h"
  30. #include "ldap_queue.h"
  31. #include "ldap_rq.h"
  32. struct re_s *
  33. ldap_pvt_runqueue_insert(
  34. struct runqueue_s* rq,
  35. time_t interval,
  36. ldap_pvt_thread_start_t *routine,
  37. void *arg,
  38. char *tname,
  39. char *tspec
  40. )
  41. {
  42. struct re_s* entry;
  43. entry = (struct re_s *) LDAP_CALLOC( 1, sizeof( struct re_s ));
  44. if ( entry ) {
  45. entry->interval.tv_sec = interval;
  46. entry->interval.tv_usec = 0;
  47. entry->next_sched.tv_sec = time( NULL );
  48. entry->next_sched.tv_usec = 0;
  49. entry->routine = routine;
  50. entry->arg = arg;
  51. entry->tname = tname;
  52. entry->tspec = tspec;
  53. LDAP_STAILQ_INSERT_HEAD( &rq->task_list, entry, tnext );
  54. }
  55. return entry;
  56. }
  57. struct re_s *
  58. ldap_pvt_runqueue_find(
  59. struct runqueue_s *rq,
  60. ldap_pvt_thread_start_t *routine,
  61. void *arg
  62. )
  63. {
  64. struct re_s* e;
  65. LDAP_STAILQ_FOREACH( e, &rq->task_list, tnext ) {
  66. if ( e->routine == routine && e->arg == arg )
  67. return e;
  68. }
  69. return NULL;
  70. }
  71. void
  72. ldap_pvt_runqueue_remove(
  73. struct runqueue_s* rq,
  74. struct re_s* entry
  75. )
  76. {
  77. struct re_s* e;
  78. LDAP_STAILQ_FOREACH( e, &rq->task_list, tnext ) {
  79. if ( e == entry)
  80. break;
  81. }
  82. assert( e == entry );
  83. LDAP_STAILQ_REMOVE( &rq->task_list, entry, re_s, tnext );
  84. LDAP_FREE( entry );
  85. }
  86. struct re_s*
  87. ldap_pvt_runqueue_next_sched(
  88. struct runqueue_s* rq,
  89. struct timeval* next_run
  90. )
  91. {
  92. struct re_s* entry;
  93. entry = LDAP_STAILQ_FIRST( &rq->task_list );
  94. if ( entry == NULL || entry->next_sched.tv_sec == 0 ) {
  95. return NULL;
  96. } else {
  97. *next_run = entry->next_sched;
  98. return entry;
  99. }
  100. }
  101. void
  102. ldap_pvt_runqueue_runtask(
  103. struct runqueue_s* rq,
  104. struct re_s* entry
  105. )
  106. {
  107. LDAP_STAILQ_INSERT_TAIL( &rq->run_list, entry, rnext );
  108. }
  109. void
  110. ldap_pvt_runqueue_stoptask(
  111. struct runqueue_s* rq,
  112. struct re_s* entry
  113. )
  114. {
  115. LDAP_STAILQ_REMOVE( &rq->run_list, entry, re_s, rnext );
  116. }
  117. int
  118. ldap_pvt_runqueue_isrunning(
  119. struct runqueue_s* rq,
  120. struct re_s* entry
  121. )
  122. {
  123. struct re_s* e;
  124. LDAP_STAILQ_FOREACH( e, &rq->run_list, rnext ) {
  125. if ( e == entry ) {
  126. return 1;
  127. }
  128. }
  129. return 0;
  130. }
  131. void
  132. ldap_pvt_runqueue_resched(
  133. struct runqueue_s* rq,
  134. struct re_s* entry,
  135. int defer
  136. )
  137. {
  138. struct re_s* prev;
  139. struct re_s* e;
  140. LDAP_STAILQ_FOREACH( e, &rq->task_list, tnext ) {
  141. if ( e == entry )
  142. break;
  143. }
  144. assert ( e == entry );
  145. LDAP_STAILQ_REMOVE( &rq->task_list, entry, re_s, tnext );
  146. if ( !defer ) {
  147. entry->next_sched.tv_sec = time( NULL ) + entry->interval.tv_sec;
  148. } else {
  149. entry->next_sched.tv_sec = 0;
  150. }
  151. if ( LDAP_STAILQ_EMPTY( &rq->task_list )) {
  152. LDAP_STAILQ_INSERT_HEAD( &rq->task_list, entry, tnext );
  153. } else if ( entry->next_sched.tv_sec == 0 ) {
  154. LDAP_STAILQ_INSERT_TAIL( &rq->task_list, entry, tnext );
  155. } else {
  156. prev = NULL;
  157. LDAP_STAILQ_FOREACH( e, &rq->task_list, tnext ) {
  158. if ( e->next_sched.tv_sec == 0 ) {
  159. if ( prev == NULL ) {
  160. LDAP_STAILQ_INSERT_HEAD( &rq->task_list, entry, tnext );
  161. } else {
  162. LDAP_STAILQ_INSERT_AFTER( &rq->task_list, prev, entry, tnext );
  163. }
  164. return;
  165. } else if ( e->next_sched.tv_sec > entry->next_sched.tv_sec ) {
  166. if ( prev == NULL ) {
  167. LDAP_STAILQ_INSERT_HEAD( &rq->task_list, entry, tnext );
  168. } else {
  169. LDAP_STAILQ_INSERT_AFTER( &rq->task_list, prev, entry, tnext );
  170. }
  171. return;
  172. }
  173. prev = e;
  174. }
  175. LDAP_STAILQ_INSERT_TAIL( &rq->task_list, entry, tnext );
  176. }
  177. }
  178. int
  179. ldap_pvt_runqueue_persistent_backload(
  180. struct runqueue_s* rq
  181. )
  182. {
  183. struct re_s* e;
  184. int count = 0;
  185. ldap_pvt_thread_mutex_lock( &rq->rq_mutex );
  186. if ( !LDAP_STAILQ_EMPTY( &rq->task_list )) {
  187. LDAP_STAILQ_FOREACH( e, &rq->task_list, tnext ) {
  188. if ( e->next_sched.tv_sec == 0 )
  189. count++;
  190. }
  191. }
  192. ldap_pvt_thread_mutex_unlock( &rq->rq_mutex );
  193. return count;
  194. }
  195. #endif /* LDAP_R_COMPILE */