]> git.sur5r.net Git - openldap/blob - libraries/libldap_r/rq.c
a runqueue for periodic thread execution (for syncrepl)
[openldap] / libraries / libldap_r / rq.c
1 /* $OpenLDAP$ */
2 #include "portable.h"
3
4 #include <stdio.h>
5
6 #include <ac/stdarg.h>
7 #include <ac/stdlib.h>
8 #include <ac/string.h>
9 #include <ac/time.h>
10 #include <ac/errno.h>
11
12 #include "ldap-int.h"
13 #include "ldap_pvt_thread.h"
14 #include "ldap_queue.h"
15 #include "ldap_rq.h"
16
17 void
18 ldap_pvt_runqueue_insert(
19         struct runqueue_s* rq,
20         time_t interval,
21         void *private
22 )
23 {
24         struct re_s* entry;
25         entry = (struct re_s *) ch_calloc( 1, sizeof( struct re_s ));
26         entry->interval.tv_sec = interval;
27         entry->interval.tv_usec = 0;
28         entry->next_sched.tv_sec = time( NULL );
29         entry->next_sched.tv_usec = 0;
30         entry->private = private;
31         LDAP_STAILQ_INSERT_HEAD( &rq->run_list, entry, next );
32 }
33
34 void
35 ldap_pvt_runqueue_next_sched(
36         struct runqueue_s* rq,
37         struct timeval** next_run,
38         void **private
39 )
40 {
41         struct re_s* entry;
42         entry = LDAP_STAILQ_FIRST( &rq->run_list );
43         if ( entry == NULL ) {
44                 *next_run = NULL;
45                 *private = NULL;
46         } else {
47                 *next_run = &entry->next_sched;
48                 *private = entry->private;
49         }
50 }
51
52 void 
53 ldap_pvt_runqueue_resched(
54         struct runqueue_s* rq
55 )
56 {
57         struct re_s* entry;
58         struct re_s* prev;
59         struct re_s* e;
60
61         entry = LDAP_STAILQ_FIRST( &rq->run_list );
62         if ( entry == NULL ) {
63                 return;
64         } else {
65                 entry->next_sched.tv_sec = time( NULL ) + entry->interval.tv_sec;
66                 LDAP_STAILQ_REMOVE_HEAD( &rq->run_list, next );
67                 if ( LDAP_STAILQ_EMPTY( &rq->run_list )) {
68                         LDAP_STAILQ_INSERT_HEAD( &rq->run_list, entry, next );
69                 } else {
70                         prev = entry;
71                         LDAP_STAILQ_FOREACH( e, &rq->run_list, next ) {
72                                 if ( e->next_sched.tv_sec > entry->next_sched.tv_sec ) {
73                                         if ( prev == entry ) {
74                                                 LDAP_STAILQ_INSERT_HEAD( &rq->run_list, entry, next );
75                                         } else {
76                                                 LDAP_STAILQ_INSERT_AFTER( &rq->run_list, prev, entry, next );
77                                         }
78                                 }
79                                 prev = e;
80                         }
81                 }
82         }
83 }