]> git.sur5r.net Git - openldap/blob - libraries/libldap_r/rq.c
eed92e72e9fa328bfdd717689afe31ce94e998d5
[openldap] / libraries / libldap_r / rq.c
1 /* $OpenLDAP$ */
2 /* 
3  * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /* Copyright (c) 2003 by International Business Machines, Inc.
7  *
8  * International Business Machines, Inc. (hereinafter called IBM) grants
9  * permission under its copyrights to use, copy, modify, and distribute this
10  * Software with or without fee, provided that the above copyright notice and
11  * all paragraphs of this notice appear in all copies, and that the name of IBM
12  * not be used in connection with the marketing of any product incorporating
13  * the Software or modifications thereof, without specific, written prior
14  * permission.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
17  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18  * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
19  * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
20  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
21  * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
22  */
23
24 #include "portable.h"
25
26 #include <stdio.h>
27
28 #include <ac/stdarg.h>
29 #include <ac/stdlib.h>
30 #include <ac/errno.h>
31 #include <ac/socket.h>
32 #include <ac/string.h>
33 #include <ac/time.h>
34
35 #include "ldap-int.h"
36 #include "ldap_pvt_thread.h"
37 #include "ldap_queue.h"
38 #include "ldap_rq.h"
39
40 void
41 ldap_pvt_runqueue_insert(
42         struct runqueue_s* rq,
43         time_t interval,
44         ldap_pvt_thread_start_t *routine,
45         void *arg
46 )
47 {
48         struct re_s* entry;
49
50         entry = (struct re_s *) LDAP_CALLOC( 1, sizeof( struct re_s ));
51         entry->interval.tv_sec = interval;
52         entry->interval.tv_usec = 0;
53         entry->next_sched.tv_sec = time( NULL );
54         entry->next_sched.tv_usec = 0;
55         entry->routine = routine;
56         entry->arg = arg;
57         LDAP_STAILQ_INSERT_HEAD( &rq->task_list, entry, tnext );
58 }
59
60 void
61 ldap_pvt_runqueue_remove(
62         struct runqueue_s* rq,
63         struct re_s* entry
64 )
65 {
66         struct re_s* e;
67
68         LDAP_STAILQ_FOREACH( e, &rq->task_list, tnext ) {
69                 if ( e == entry)
70                         break;
71         }
72
73         assert ( e == entry );
74
75         LDAP_STAILQ_REMOVE( &rq->task_list, entry, re_s, tnext );
76
77         LDAP_FREE( entry );
78
79 }
80
81 struct re_s*
82 ldap_pvt_runqueue_next_sched(
83         struct runqueue_s* rq,
84         struct timeval** next_run
85 )
86 {
87         struct re_s* entry;
88
89         entry = LDAP_STAILQ_FIRST( &rq->task_list );
90         if ( entry == NULL ) {
91                 *next_run = NULL;
92                 return NULL;
93         } else if ( entry->next_sched.tv_sec == 0 ) {
94                 *next_run = NULL;
95                 return NULL;
96         } else {
97                 *next_run = &entry->next_sched;
98                 return entry;
99         }
100 }
101
102 void
103 ldap_pvt_runqueue_runtask(
104         struct runqueue_s* rq,
105         struct re_s* entry
106 )
107 {
108         LDAP_STAILQ_INSERT_HEAD( &rq->run_list, entry, rnext );
109 }
110
111 void
112 ldap_pvt_runqueue_stoptask(
113         struct runqueue_s* rq,
114         struct re_s* entry
115 )
116 {
117         LDAP_STAILQ_REMOVE( &rq->run_list, entry, re_s, rnext );
118 }
119
120 int
121 ldap_pvt_runqueue_isrunning(
122         struct runqueue_s* rq,
123         struct re_s* entry
124 )
125 {
126         struct re_s* e;
127
128         LDAP_STAILQ_FOREACH( e, &rq->run_list, rnext ) {
129                 if ( e == entry ) {
130                         return 1;
131                 }
132         }
133         return 0;
134 }
135
136 void 
137 ldap_pvt_runqueue_resched(
138         struct runqueue_s* rq,
139         struct re_s* entry,
140         int defer
141 )
142 {
143         struct re_s* prev;
144         struct re_s* e;
145
146         LDAP_STAILQ_FOREACH( e, &rq->task_list, tnext ) {
147                 if ( e == entry )
148                         break;
149         }
150
151         assert ( e == entry );
152
153         LDAP_STAILQ_REMOVE( &rq->task_list, entry, re_s, tnext );
154
155         if ( entry->interval.tv_sec && !defer ) {
156                 entry->next_sched.tv_sec = time( NULL ) + entry->interval.tv_sec;
157         } else {
158                 entry->next_sched.tv_sec = 0;
159         }
160
161         if ( LDAP_STAILQ_EMPTY( &rq->task_list )) {
162                 LDAP_STAILQ_INSERT_HEAD( &rq->task_list, entry, tnext );
163         } else if ( entry->next_sched.tv_sec == 0 ) {
164                 LDAP_STAILQ_INSERT_TAIL( &rq->task_list, entry, tnext );
165         } else {
166                 prev = NULL;
167                 LDAP_STAILQ_FOREACH( e, &rq->task_list, tnext ) {
168                         if ( e->next_sched.tv_sec == 0 ) {
169                                 if ( prev == NULL ) {
170                                         LDAP_STAILQ_INSERT_HEAD( &rq->task_list, entry, tnext );
171                                 } else {
172                                         LDAP_STAILQ_INSERT_AFTER( &rq->task_list, prev, entry, tnext );
173                                 }
174                                 break;
175                         } else if ( e->next_sched.tv_sec > entry->next_sched.tv_sec ) {
176                                 if ( prev == NULL ) {
177                                         LDAP_STAILQ_INSERT_HEAD( &rq->task_list, entry, tnext );
178                                 } else {
179                                         LDAP_STAILQ_INSERT_AFTER( &rq->task_list, prev, entry, tnext );
180                                 }
181                                 break;
182                         }
183                         prev = e;
184                 }
185         }
186 }
187
188 int
189 ldap_pvt_runqueue_persistent_backload(
190         struct runqueue_s* rq
191 )
192 {
193         struct re_s* e;
194         int count = 0;
195
196         ldap_pvt_thread_mutex_lock( &rq->rq_mutex );
197         if ( !LDAP_STAILQ_EMPTY( &rq->task_list )) {
198                 LDAP_STAILQ_FOREACH( e, &rq->task_list, tnext ) {
199                         if ( e->next_sched.tv_sec == 0 )
200                                 count++;
201                 }
202         }
203         ldap_pvt_thread_mutex_unlock( &rq->rq_mutex );
204         return count;
205 }
206