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