xref: /freebsd/contrib/ntp/libntp/lib/isc/include/isc/task.h (revision a466cc55)
1*a466cc55SCy Schubert /*
2*a466cc55SCy Schubert  * Copyright (C) 2004-2007, 2009-2012  Internet Systems Consortium, Inc. ("ISC")
3*a466cc55SCy Schubert  * Copyright (C) 1998-2001, 2003  Internet Software Consortium.
4*a466cc55SCy Schubert  *
5*a466cc55SCy Schubert  * Permission to use, copy, modify, and/or distribute this software for any
6*a466cc55SCy Schubert  * purpose with or without fee is hereby granted, provided that the above
7*a466cc55SCy Schubert  * copyright notice and this permission notice appear in all copies.
8*a466cc55SCy Schubert  *
9*a466cc55SCy Schubert  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10*a466cc55SCy Schubert  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11*a466cc55SCy Schubert  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12*a466cc55SCy Schubert  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13*a466cc55SCy Schubert  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14*a466cc55SCy Schubert  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15*a466cc55SCy Schubert  * PERFORMANCE OF THIS SOFTWARE.
16*a466cc55SCy Schubert  */
17*a466cc55SCy Schubert 
18*a466cc55SCy Schubert /* $Id$ */
19*a466cc55SCy Schubert 
20*a466cc55SCy Schubert #ifndef ISC_TASK_H
21*a466cc55SCy Schubert #define ISC_TASK_H 1
22*a466cc55SCy Schubert 
23*a466cc55SCy Schubert /*****
24*a466cc55SCy Schubert  ***** Module Info
25*a466cc55SCy Schubert  *****/
26*a466cc55SCy Schubert 
27*a466cc55SCy Schubert /*! \file isc/task.h
28*a466cc55SCy Schubert  * \brief The task system provides a lightweight execution context, which is
29*a466cc55SCy Schubert  * basically an event queue.
30*a466cc55SCy Schubert 
31*a466cc55SCy Schubert  * When a task's event queue is non-empty, the
32*a466cc55SCy Schubert  * task is runnable.  A small work crew of threads, typically one per CPU,
33*a466cc55SCy Schubert  * execute runnable tasks by dispatching the events on the tasks' event
34*a466cc55SCy Schubert  * queues.  Context switching between tasks is fast.
35*a466cc55SCy Schubert  *
36*a466cc55SCy Schubert  * \li MP:
37*a466cc55SCy Schubert  *	The module ensures appropriate synchronization of data structures it
38*a466cc55SCy Schubert  *	creates and manipulates.
39*a466cc55SCy Schubert  *	The caller must ensure that isc_taskmgr_destroy() is called only
40*a466cc55SCy Schubert  *	once for a given manager.
41*a466cc55SCy Schubert  *
42*a466cc55SCy Schubert  * \li Reliability:
43*a466cc55SCy Schubert  *	No anticipated impact.
44*a466cc55SCy Schubert  *
45*a466cc55SCy Schubert  * \li Resources:
46*a466cc55SCy Schubert  *	TBS
47*a466cc55SCy Schubert  *
48*a466cc55SCy Schubert  * \li Security:
49*a466cc55SCy Schubert  *	No anticipated impact.
50*a466cc55SCy Schubert  *
51*a466cc55SCy Schubert  * \li Standards:
52*a466cc55SCy Schubert  *	None.
53*a466cc55SCy Schubert  *
54*a466cc55SCy Schubert  * \section purge Purging and Unsending
55*a466cc55SCy Schubert  *
56*a466cc55SCy Schubert  * Events which have been queued for a task but not delivered may be removed
57*a466cc55SCy Schubert  * from the task's event queue by purging or unsending.
58*a466cc55SCy Schubert  *
59*a466cc55SCy Schubert  * With both types, the caller specifies a matching pattern that selects
60*a466cc55SCy Schubert  * events based upon their sender, type, and tag.
61*a466cc55SCy Schubert  *
62*a466cc55SCy Schubert  * Purging calls isc_event_free() on the matching events.
63*a466cc55SCy Schubert  *
64*a466cc55SCy Schubert  * Unsending returns a list of events that matched the pattern.
65*a466cc55SCy Schubert  * The caller is then responsible for them.
66*a466cc55SCy Schubert  *
67*a466cc55SCy Schubert  * Consumers of events should purge, not unsend.
68*a466cc55SCy Schubert  *
69*a466cc55SCy Schubert  * Producers of events often want to remove events when the caller indicates
70*a466cc55SCy Schubert  * it is no longer interested in the object, e.g. by canceling a timer.
71*a466cc55SCy Schubert  * Sometimes this can be done by purging, but for some event types, the
72*a466cc55SCy Schubert  * calls to isc_event_free() cause deadlock because the event free routine
73*a466cc55SCy Schubert  * wants to acquire a lock the caller is already holding.  Unsending instead
74*a466cc55SCy Schubert  * of purging solves this problem.  As a general rule, producers should only
75*a466cc55SCy Schubert  * unsend events which they have sent.
76*a466cc55SCy Schubert  */
77*a466cc55SCy Schubert 
78*a466cc55SCy Schubert 
79*a466cc55SCy Schubert /***
80*a466cc55SCy Schubert  *** Imports.
81*a466cc55SCy Schubert  ***/
82*a466cc55SCy Schubert 
83*a466cc55SCy Schubert #include <isc/eventclass.h>
84*a466cc55SCy Schubert #include <isc/lang.h>
85*a466cc55SCy Schubert #include <isc/stdtime.h>
86*a466cc55SCy Schubert #include <isc/types.h>
87*a466cc55SCy Schubert #include <isc/xml.h>
88*a466cc55SCy Schubert 
89*a466cc55SCy Schubert #define ISC_TASKEVENT_FIRSTEVENT	(ISC_EVENTCLASS_TASK + 0)
90*a466cc55SCy Schubert #define ISC_TASKEVENT_SHUTDOWN		(ISC_EVENTCLASS_TASK + 1)
91*a466cc55SCy Schubert #define ISC_TASKEVENT_TEST		(ISC_EVENTCLASS_TASK + 1)
92*a466cc55SCy Schubert #define ISC_TASKEVENT_LASTEVENT		(ISC_EVENTCLASS_TASK + 65535)
93*a466cc55SCy Schubert 
94*a466cc55SCy Schubert /*****
95*a466cc55SCy Schubert  ***** Tasks.
96*a466cc55SCy Schubert  *****/
97*a466cc55SCy Schubert 
98*a466cc55SCy Schubert ISC_LANG_BEGINDECLS
99*a466cc55SCy Schubert 
100*a466cc55SCy Schubert /***
101*a466cc55SCy Schubert  *** Types
102*a466cc55SCy Schubert  ***/
103*a466cc55SCy Schubert 
104*a466cc55SCy Schubert typedef enum {
105*a466cc55SCy Schubert 		isc_taskmgrmode_normal = 0,
106*a466cc55SCy Schubert 		isc_taskmgrmode_privileged
107*a466cc55SCy Schubert } isc_taskmgrmode_t;
108*a466cc55SCy Schubert 
109*a466cc55SCy Schubert /*% Task and task manager methods */
110*a466cc55SCy Schubert typedef struct isc_taskmgrmethods {
111*a466cc55SCy Schubert 	void		(*destroy)(isc_taskmgr_t **managerp);
112*a466cc55SCy Schubert 	void		(*setmode)(isc_taskmgr_t *manager,
113*a466cc55SCy Schubert 				   isc_taskmgrmode_t mode);
114*a466cc55SCy Schubert 	isc_taskmgrmode_t (*mode)(isc_taskmgr_t *manager);
115*a466cc55SCy Schubert 	isc_result_t	(*taskcreate)(isc_taskmgr_t *manager,
116*a466cc55SCy Schubert 				      unsigned int quantum,
117*a466cc55SCy Schubert 				      isc_task_t **taskp);
118*a466cc55SCy Schubert } isc_taskmgrmethods_t;
119*a466cc55SCy Schubert 
120*a466cc55SCy Schubert typedef struct isc_taskmethods {
121*a466cc55SCy Schubert 	void (*attach)(isc_task_t *source, isc_task_t **targetp);
122*a466cc55SCy Schubert 	void (*detach)(isc_task_t **taskp);
123*a466cc55SCy Schubert 	void (*destroy)(isc_task_t **taskp);
124*a466cc55SCy Schubert 	void (*send)(isc_task_t *task, isc_event_t **eventp);
125*a466cc55SCy Schubert 	void (*sendanddetach)(isc_task_t **taskp, isc_event_t **eventp);
126*a466cc55SCy Schubert 	unsigned int (*unsend)(isc_task_t *task, void *sender, isc_eventtype_t type,
127*a466cc55SCy Schubert 			       void *tag, isc_eventlist_t *events);
128*a466cc55SCy Schubert 	isc_result_t (*onshutdown)(isc_task_t *task, isc_taskaction_t action,
129*a466cc55SCy Schubert 				   const void *arg);
130*a466cc55SCy Schubert 	void (*shutdown)(isc_task_t *task);
131*a466cc55SCy Schubert 	void (*setname)(isc_task_t *task, const char *name, void *tag);
132*a466cc55SCy Schubert 	unsigned int (*purgeevents)(isc_task_t *task, void *sender,
133*a466cc55SCy Schubert 				    isc_eventtype_t type, void *tag);
134*a466cc55SCy Schubert 	unsigned int (*purgerange)(isc_task_t *task, void *sender,
135*a466cc55SCy Schubert 				   isc_eventtype_t first, isc_eventtype_t last,
136*a466cc55SCy Schubert 				   void *tag);
137*a466cc55SCy Schubert 	isc_result_t (*beginexclusive)(isc_task_t *task);
138*a466cc55SCy Schubert 	void (*endexclusive)(isc_task_t *task);
139*a466cc55SCy Schubert     void (*setprivilege)(isc_task_t *task, isc_boolean_t priv);
140*a466cc55SCy Schubert     isc_boolean_t (*privilege)(isc_task_t *task);
141*a466cc55SCy Schubert } isc_taskmethods_t;
142*a466cc55SCy Schubert 
143*a466cc55SCy Schubert /*%
144*a466cc55SCy Schubert  * This structure is actually just the common prefix of a task manager
145*a466cc55SCy Schubert  * object implementation's version of an isc_taskmgr_t.
146*a466cc55SCy Schubert  * \brief
147*a466cc55SCy Schubert  * Direct use of this structure by clients is forbidden.  task implementations
148*a466cc55SCy Schubert  * may change the structure.  'magic' must be ISCAPI_TASKMGR_MAGIC for any
149*a466cc55SCy Schubert  * of the isc_task_ routines to work.  task implementations must maintain
150*a466cc55SCy Schubert  * all task invariants.
151*a466cc55SCy Schubert  */
152*a466cc55SCy Schubert struct isc_taskmgr {
153*a466cc55SCy Schubert 	unsigned int		impmagic;
154*a466cc55SCy Schubert 	unsigned int		magic;
155*a466cc55SCy Schubert 	isc_taskmgrmethods_t	*methods;
156*a466cc55SCy Schubert };
157*a466cc55SCy Schubert 
158*a466cc55SCy Schubert #define ISCAPI_TASKMGR_MAGIC	ISC_MAGIC('A','t','m','g')
159*a466cc55SCy Schubert #define ISCAPI_TASKMGR_VALID(m)	((m) != NULL && \
160*a466cc55SCy Schubert 				 (m)->magic == ISCAPI_TASKMGR_MAGIC)
161*a466cc55SCy Schubert 
162*a466cc55SCy Schubert /*%
163*a466cc55SCy Schubert  * This is the common prefix of a task object.  The same note as
164*a466cc55SCy Schubert  * that for the taskmgr structure applies.
165*a466cc55SCy Schubert  */
166*a466cc55SCy Schubert struct isc_task {
167*a466cc55SCy Schubert 	unsigned int		impmagic;
168*a466cc55SCy Schubert 	unsigned int		magic;
169*a466cc55SCy Schubert 	isc_taskmethods_t	*methods;
170*a466cc55SCy Schubert };
171*a466cc55SCy Schubert 
172*a466cc55SCy Schubert #define ISCAPI_TASK_MAGIC	ISC_MAGIC('A','t','s','t')
173*a466cc55SCy Schubert #define ISCAPI_TASK_VALID(s)	((s) != NULL && \
174*a466cc55SCy Schubert 				 (s)->magic == ISCAPI_TASK_MAGIC)
175*a466cc55SCy Schubert 
176*a466cc55SCy Schubert isc_result_t
177*a466cc55SCy Schubert isc_task_create(isc_taskmgr_t *manager, unsigned int quantum,
178*a466cc55SCy Schubert 		isc_task_t **taskp);
179*a466cc55SCy Schubert /*%<
180*a466cc55SCy Schubert  * Create a task.
181*a466cc55SCy Schubert  *
182*a466cc55SCy Schubert  * Notes:
183*a466cc55SCy Schubert  *
184*a466cc55SCy Schubert  *\li	If 'quantum' is non-zero, then only that many events can be dispatched
185*a466cc55SCy Schubert  *	before the task must yield to other tasks waiting to execute.  If
186*a466cc55SCy Schubert  *	quantum is zero, then the default quantum of the task manager will
187*a466cc55SCy Schubert  *	be used.
188*a466cc55SCy Schubert  *
189*a466cc55SCy Schubert  *\li	The 'quantum' option may be removed from isc_task_create() in the
190*a466cc55SCy Schubert  *	future.  If this happens, isc_task_getquantum() and
191*a466cc55SCy Schubert  *	isc_task_setquantum() will be provided.
192*a466cc55SCy Schubert  *
193*a466cc55SCy Schubert  * Requires:
194*a466cc55SCy Schubert  *
195*a466cc55SCy Schubert  *\li	'manager' is a valid task manager.
196*a466cc55SCy Schubert  *
197*a466cc55SCy Schubert  *\li	taskp != NULL && *taskp == NULL
198*a466cc55SCy Schubert  *
199*a466cc55SCy Schubert  * Ensures:
200*a466cc55SCy Schubert  *
201*a466cc55SCy Schubert  *\li	On success, '*taskp' is bound to the new task.
202*a466cc55SCy Schubert  *
203*a466cc55SCy Schubert  * Returns:
204*a466cc55SCy Schubert  *
205*a466cc55SCy Schubert  *\li   #ISC_R_SUCCESS
206*a466cc55SCy Schubert  *\li	#ISC_R_NOMEMORY
207*a466cc55SCy Schubert  *\li	#ISC_R_UNEXPECTED
208*a466cc55SCy Schubert  *\li	#ISC_R_SHUTTINGDOWN
209*a466cc55SCy Schubert  */
210*a466cc55SCy Schubert 
211*a466cc55SCy Schubert void
212*a466cc55SCy Schubert isc_task_attach(isc_task_t *source, isc_task_t **targetp);
213*a466cc55SCy Schubert /*%<
214*a466cc55SCy Schubert  * Attach *targetp to source.
215*a466cc55SCy Schubert  *
216*a466cc55SCy Schubert  * Requires:
217*a466cc55SCy Schubert  *
218*a466cc55SCy Schubert  *\li	'source' is a valid task.
219*a466cc55SCy Schubert  *
220*a466cc55SCy Schubert  *\li	'targetp' points to a NULL isc_task_t *.
221*a466cc55SCy Schubert  *
222*a466cc55SCy Schubert  * Ensures:
223*a466cc55SCy Schubert  *
224*a466cc55SCy Schubert  *\li	*targetp is attached to source.
225*a466cc55SCy Schubert  */
226*a466cc55SCy Schubert 
227*a466cc55SCy Schubert void
228*a466cc55SCy Schubert isc_task_detach(isc_task_t **taskp);
229*a466cc55SCy Schubert /*%<
230*a466cc55SCy Schubert  * Detach *taskp from its task.
231*a466cc55SCy Schubert  *
232*a466cc55SCy Schubert  * Requires:
233*a466cc55SCy Schubert  *
234*a466cc55SCy Schubert  *\li	'*taskp' is a valid task.
235*a466cc55SCy Schubert  *
236*a466cc55SCy Schubert  * Ensures:
237*a466cc55SCy Schubert  *
238*a466cc55SCy Schubert  *\li	*taskp is NULL.
239*a466cc55SCy Schubert  *
240*a466cc55SCy Schubert  *\li	If '*taskp' is the last reference to the task, the task is idle (has
241*a466cc55SCy Schubert  *	an empty event queue), and has not been shutdown, the task will be
242*a466cc55SCy Schubert  *	shutdown.
243*a466cc55SCy Schubert  *
244*a466cc55SCy Schubert  *\li	If '*taskp' is the last reference to the task and
245*a466cc55SCy Schubert  *	the task has been shutdown,
246*a466cc55SCy Schubert  *		all resources used by the task will be freed.
247*a466cc55SCy Schubert  */
248*a466cc55SCy Schubert 
249*a466cc55SCy Schubert void
250*a466cc55SCy Schubert isc_task_send(isc_task_t *task, isc_event_t **eventp);
251*a466cc55SCy Schubert /*%<
252*a466cc55SCy Schubert  * Send '*event' to 'task'.
253*a466cc55SCy Schubert  *
254*a466cc55SCy Schubert  * Requires:
255*a466cc55SCy Schubert  *
256*a466cc55SCy Schubert  *\li	'task' is a valid task.
257*a466cc55SCy Schubert  *\li	eventp != NULL && *eventp != NULL.
258*a466cc55SCy Schubert  *
259*a466cc55SCy Schubert  * Ensures:
260*a466cc55SCy Schubert  *
261*a466cc55SCy Schubert  *\li	*eventp == NULL.
262*a466cc55SCy Schubert  */
263*a466cc55SCy Schubert 
264*a466cc55SCy Schubert void
265*a466cc55SCy Schubert isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp);
266*a466cc55SCy Schubert /*%<
267*a466cc55SCy Schubert  * Send '*event' to '*taskp' and then detach '*taskp' from its
268*a466cc55SCy Schubert  * task.
269*a466cc55SCy Schubert  *
270*a466cc55SCy Schubert  * Requires:
271*a466cc55SCy Schubert  *
272*a466cc55SCy Schubert  *\li	'*taskp' is a valid task.
273*a466cc55SCy Schubert  *\li	eventp != NULL && *eventp != NULL.
274*a466cc55SCy Schubert  *
275*a466cc55SCy Schubert  * Ensures:
276*a466cc55SCy Schubert  *
277*a466cc55SCy Schubert  *\li	*eventp == NULL.
278*a466cc55SCy Schubert  *
279*a466cc55SCy Schubert  *\li	*taskp == NULL.
280*a466cc55SCy Schubert  *
281*a466cc55SCy Schubert  *\li	If '*taskp' is the last reference to the task, the task is
282*a466cc55SCy Schubert  *	idle (has an empty event queue), and has not been shutdown,
283*a466cc55SCy Schubert  *	the task will be shutdown.
284*a466cc55SCy Schubert  *
285*a466cc55SCy Schubert  *\li	If '*taskp' is the last reference to the task and
286*a466cc55SCy Schubert  *	the task has been shutdown,
287*a466cc55SCy Schubert  *		all resources used by the task will be freed.
288*a466cc55SCy Schubert  */
289*a466cc55SCy Schubert 
290*a466cc55SCy Schubert 
291*a466cc55SCy Schubert unsigned int
292*a466cc55SCy Schubert isc_task_purgerange(isc_task_t *task, void *sender, isc_eventtype_t first,
293*a466cc55SCy Schubert 		    isc_eventtype_t last, void *tag);
294*a466cc55SCy Schubert /*%<
295*a466cc55SCy Schubert  * Purge events from a task's event queue.
296*a466cc55SCy Schubert  *
297*a466cc55SCy Schubert  * Requires:
298*a466cc55SCy Schubert  *
299*a466cc55SCy Schubert  *\li	'task' is a valid task.
300*a466cc55SCy Schubert  *
301*a466cc55SCy Schubert  *\li	last >= first
302*a466cc55SCy Schubert  *
303*a466cc55SCy Schubert  * Ensures:
304*a466cc55SCy Schubert  *
305*a466cc55SCy Schubert  *\li	Events in the event queue of 'task' whose sender is 'sender', whose
306*a466cc55SCy Schubert  *	type is >= first and <= last, and whose tag is 'tag' will be purged,
307*a466cc55SCy Schubert  *	unless they are marked as unpurgable.
308*a466cc55SCy Schubert  *
309*a466cc55SCy Schubert  *\li	A sender of NULL will match any sender.  A NULL tag matches any
310*a466cc55SCy Schubert  *	tag.
311*a466cc55SCy Schubert  *
312*a466cc55SCy Schubert  * Returns:
313*a466cc55SCy Schubert  *
314*a466cc55SCy Schubert  *\li	The number of events purged.
315*a466cc55SCy Schubert  */
316*a466cc55SCy Schubert 
317*a466cc55SCy Schubert unsigned int
318*a466cc55SCy Schubert isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type,
319*a466cc55SCy Schubert 	       void *tag);
320*a466cc55SCy Schubert /*%<
321*a466cc55SCy Schubert  * Purge events from a task's event queue.
322*a466cc55SCy Schubert  *
323*a466cc55SCy Schubert  * Notes:
324*a466cc55SCy Schubert  *
325*a466cc55SCy Schubert  *\li	This function is equivalent to
326*a466cc55SCy Schubert  *
327*a466cc55SCy Schubert  *\code
328*a466cc55SCy Schubert  *		isc_task_purgerange(task, sender, type, type, tag);
329*a466cc55SCy Schubert  *\endcode
330*a466cc55SCy Schubert  *
331*a466cc55SCy Schubert  * Requires:
332*a466cc55SCy Schubert  *
333*a466cc55SCy Schubert  *\li	'task' is a valid task.
334*a466cc55SCy Schubert  *
335*a466cc55SCy Schubert  * Ensures:
336*a466cc55SCy Schubert  *
337*a466cc55SCy Schubert  *\li	Events in the event queue of 'task' whose sender is 'sender', whose
338*a466cc55SCy Schubert  *	type is 'type', and whose tag is 'tag' will be purged, unless they
339*a466cc55SCy Schubert  *	are marked as unpurgable.
340*a466cc55SCy Schubert  *
341*a466cc55SCy Schubert  *\li	A sender of NULL will match any sender.  A NULL tag matches any
342*a466cc55SCy Schubert  *	tag.
343*a466cc55SCy Schubert  *
344*a466cc55SCy Schubert  * Returns:
345*a466cc55SCy Schubert  *
346*a466cc55SCy Schubert  *\li	The number of events purged.
347*a466cc55SCy Schubert  */
348*a466cc55SCy Schubert 
349*a466cc55SCy Schubert isc_boolean_t
350*a466cc55SCy Schubert isc_task_purgeevent(isc_task_t *task, isc_event_t *event);
351*a466cc55SCy Schubert /*%<
352*a466cc55SCy Schubert  * Purge 'event' from a task's event queue.
353*a466cc55SCy Schubert  *
354*a466cc55SCy Schubert  * XXXRTH:  WARNING:  This method may be removed before beta.
355*a466cc55SCy Schubert  *
356*a466cc55SCy Schubert  * Notes:
357*a466cc55SCy Schubert  *
358*a466cc55SCy Schubert  *\li	If 'event' is on the task's event queue, it will be purged,
359*a466cc55SCy Schubert  * 	unless it is marked as unpurgeable.  'event' does not have to be
360*a466cc55SCy Schubert  *	on the task's event queue; in fact, it can even be an invalid
361*a466cc55SCy Schubert  *	pointer.  Purging only occurs if the event is actually on the task's
362*a466cc55SCy Schubert  *	event queue.
363*a466cc55SCy Schubert  *
364*a466cc55SCy Schubert  * \li	Purging never changes the state of the task.
365*a466cc55SCy Schubert  *
366*a466cc55SCy Schubert  * Requires:
367*a466cc55SCy Schubert  *
368*a466cc55SCy Schubert  *\li	'task' is a valid task.
369*a466cc55SCy Schubert  *
370*a466cc55SCy Schubert  * Ensures:
371*a466cc55SCy Schubert  *
372*a466cc55SCy Schubert  *\li	'event' is not in the event queue for 'task'.
373*a466cc55SCy Schubert  *
374*a466cc55SCy Schubert  * Returns:
375*a466cc55SCy Schubert  *
376*a466cc55SCy Schubert  *\li	#ISC_TRUE			The event was purged.
377*a466cc55SCy Schubert  *\li	#ISC_FALSE			The event was not in the event queue,
378*a466cc55SCy Schubert  *					or was marked unpurgeable.
379*a466cc55SCy Schubert  */
380*a466cc55SCy Schubert 
381*a466cc55SCy Schubert unsigned int
382*a466cc55SCy Schubert isc_task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first,
383*a466cc55SCy Schubert 		     isc_eventtype_t last, void *tag, isc_eventlist_t *events);
384*a466cc55SCy Schubert /*%<
385*a466cc55SCy Schubert  * Remove events from a task's event queue.
386*a466cc55SCy Schubert  *
387*a466cc55SCy Schubert  * Requires:
388*a466cc55SCy Schubert  *
389*a466cc55SCy Schubert  *\li	'task' is a valid task.
390*a466cc55SCy Schubert  *
391*a466cc55SCy Schubert  *\li	last >= first.
392*a466cc55SCy Schubert  *
393*a466cc55SCy Schubert  *\li	*events is a valid list.
394*a466cc55SCy Schubert  *
395*a466cc55SCy Schubert  * Ensures:
396*a466cc55SCy Schubert  *
397*a466cc55SCy Schubert  *\li	Events in the event queue of 'task' whose sender is 'sender', whose
398*a466cc55SCy Schubert  *	type is >= first and <= last, and whose tag is 'tag' will be dequeued
399*a466cc55SCy Schubert  *	and appended to *events.
400*a466cc55SCy Schubert  *
401*a466cc55SCy Schubert  *\li	A sender of NULL will match any sender.  A NULL tag matches any
402*a466cc55SCy Schubert  *	tag.
403*a466cc55SCy Schubert  *
404*a466cc55SCy Schubert  * Returns:
405*a466cc55SCy Schubert  *
406*a466cc55SCy Schubert  *\li	The number of events unsent.
407*a466cc55SCy Schubert  */
408*a466cc55SCy Schubert 
409*a466cc55SCy Schubert unsigned int
410*a466cc55SCy Schubert isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
411*a466cc55SCy Schubert 		void *tag, isc_eventlist_t *events);
412*a466cc55SCy Schubert /*%<
413*a466cc55SCy Schubert  * Remove events from a task's event queue.
414*a466cc55SCy Schubert  *
415*a466cc55SCy Schubert  * Notes:
416*a466cc55SCy Schubert  *
417*a466cc55SCy Schubert  *\li	This function is equivalent to
418*a466cc55SCy Schubert  *
419*a466cc55SCy Schubert  *\code
420*a466cc55SCy Schubert  *		isc_task_unsendrange(task, sender, type, type, tag, events);
421*a466cc55SCy Schubert  *\endcode
422*a466cc55SCy Schubert  *
423*a466cc55SCy Schubert  * Requires:
424*a466cc55SCy Schubert  *
425*a466cc55SCy Schubert  *\li	'task' is a valid task.
426*a466cc55SCy Schubert  *
427*a466cc55SCy Schubert  *\li	*events is a valid list.
428*a466cc55SCy Schubert  *
429*a466cc55SCy Schubert  * Ensures:
430*a466cc55SCy Schubert  *
431*a466cc55SCy Schubert  *\li	Events in the event queue of 'task' whose sender is 'sender', whose
432*a466cc55SCy Schubert  *	type is 'type', and whose tag is 'tag' will be dequeued and appended
433*a466cc55SCy Schubert  *	to *events.
434*a466cc55SCy Schubert  *
435*a466cc55SCy Schubert  * Returns:
436*a466cc55SCy Schubert  *
437*a466cc55SCy Schubert  *\li	The number of events unsent.
438*a466cc55SCy Schubert  */
439*a466cc55SCy Schubert 
440*a466cc55SCy Schubert isc_result_t
441*a466cc55SCy Schubert isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action,
442*a466cc55SCy Schubert 		    const void *arg);
443*a466cc55SCy Schubert /*%<
444*a466cc55SCy Schubert  * Send a shutdown event with action 'action' and argument 'arg' when
445*a466cc55SCy Schubert  * 'task' is shutdown.
446*a466cc55SCy Schubert  *
447*a466cc55SCy Schubert  * Notes:
448*a466cc55SCy Schubert  *
449*a466cc55SCy Schubert  *\li	Shutdown events are posted in LIFO order.
450*a466cc55SCy Schubert  *
451*a466cc55SCy Schubert  * Requires:
452*a466cc55SCy Schubert  *
453*a466cc55SCy Schubert  *\li	'task' is a valid task.
454*a466cc55SCy Schubert  *
455*a466cc55SCy Schubert  *\li	'action' is a valid task action.
456*a466cc55SCy Schubert  *
457*a466cc55SCy Schubert  * Ensures:
458*a466cc55SCy Schubert  *
459*a466cc55SCy Schubert  *\li	When the task is shutdown, shutdown events requested with
460*a466cc55SCy Schubert  *	isc_task_onshutdown() will be appended to the task's event queue.
461*a466cc55SCy Schubert  *
462*a466cc55SCy Schubert 
463*a466cc55SCy Schubert  * Returns:
464*a466cc55SCy Schubert  *
465*a466cc55SCy Schubert  *\li	#ISC_R_SUCCESS
466*a466cc55SCy Schubert  *\li	#ISC_R_NOMEMORY
467*a466cc55SCy Schubert  *\li	#ISC_R_TASKSHUTTINGDOWN			Task is shutting down.
468*a466cc55SCy Schubert  */
469*a466cc55SCy Schubert 
470*a466cc55SCy Schubert void
471*a466cc55SCy Schubert isc_task_shutdown(isc_task_t *task);
472*a466cc55SCy Schubert /*%<
473*a466cc55SCy Schubert  * Shutdown 'task'.
474*a466cc55SCy Schubert  *
475*a466cc55SCy Schubert  * Notes:
476*a466cc55SCy Schubert  *
477*a466cc55SCy Schubert  *\li	Shutting down a task causes any shutdown events requested with
478*a466cc55SCy Schubert  *	isc_task_onshutdown() to be posted (in LIFO order).  The task
479*a466cc55SCy Schubert  *	moves into a "shutting down" mode which prevents further calls
480*a466cc55SCy Schubert  *	to isc_task_onshutdown().
481*a466cc55SCy Schubert  *
482*a466cc55SCy Schubert  *\li	Trying to shutdown a task that has already been shutdown has no
483*a466cc55SCy Schubert  *	effect.
484*a466cc55SCy Schubert  *
485*a466cc55SCy Schubert  * Requires:
486*a466cc55SCy Schubert  *
487*a466cc55SCy Schubert  *\li	'task' is a valid task.
488*a466cc55SCy Schubert  *
489*a466cc55SCy Schubert  * Ensures:
490*a466cc55SCy Schubert  *
491*a466cc55SCy Schubert  *\li	Any shutdown events requested with isc_task_onshutdown() have been
492*a466cc55SCy Schubert  *	posted (in LIFO order).
493*a466cc55SCy Schubert  */
494*a466cc55SCy Schubert 
495*a466cc55SCy Schubert void
496*a466cc55SCy Schubert isc_task_destroy(isc_task_t **taskp);
497*a466cc55SCy Schubert /*%<
498*a466cc55SCy Schubert  * Destroy '*taskp'.
499*a466cc55SCy Schubert  *
500*a466cc55SCy Schubert  * Notes:
501*a466cc55SCy Schubert  *
502*a466cc55SCy Schubert  *\li	This call is equivalent to:
503*a466cc55SCy Schubert  *
504*a466cc55SCy Schubert  *\code
505*a466cc55SCy Schubert  *		isc_task_shutdown(*taskp);
506*a466cc55SCy Schubert  *		isc_task_detach(taskp);
507*a466cc55SCy Schubert  *\endcode
508*a466cc55SCy Schubert  *
509*a466cc55SCy Schubert  * Requires:
510*a466cc55SCy Schubert  *
511*a466cc55SCy Schubert  *	'*taskp' is a valid task.
512*a466cc55SCy Schubert  *
513*a466cc55SCy Schubert  * Ensures:
514*a466cc55SCy Schubert  *
515*a466cc55SCy Schubert  *\li	Any shutdown events requested with isc_task_onshutdown() have been
516*a466cc55SCy Schubert  *	posted (in LIFO order).
517*a466cc55SCy Schubert  *
518*a466cc55SCy Schubert  *\li	*taskp == NULL
519*a466cc55SCy Schubert  *
520*a466cc55SCy Schubert  *\li	If '*taskp' is the last reference to the task,
521*a466cc55SCy Schubert  *		all resources used by the task will be freed.
522*a466cc55SCy Schubert  */
523*a466cc55SCy Schubert 
524*a466cc55SCy Schubert void
525*a466cc55SCy Schubert isc_task_setname(isc_task_t *task, const char *name, void *tag);
526*a466cc55SCy Schubert /*%<
527*a466cc55SCy Schubert  * Name 'task'.
528*a466cc55SCy Schubert  *
529*a466cc55SCy Schubert  * Notes:
530*a466cc55SCy Schubert  *
531*a466cc55SCy Schubert  *\li	Only the first 15 characters of 'name' will be copied.
532*a466cc55SCy Schubert  *
533*a466cc55SCy Schubert  *\li	Naming a task is currently only useful for debugging purposes.
534*a466cc55SCy Schubert  *
535*a466cc55SCy Schubert  * Requires:
536*a466cc55SCy Schubert  *
537*a466cc55SCy Schubert  *\li	'task' is a valid task.
538*a466cc55SCy Schubert  */
539*a466cc55SCy Schubert 
540*a466cc55SCy Schubert const char *
541*a466cc55SCy Schubert isc_task_getname(isc_task_t *task);
542*a466cc55SCy Schubert /*%<
543*a466cc55SCy Schubert  * Get the name of 'task', as previously set using isc_task_setname().
544*a466cc55SCy Schubert  *
545*a466cc55SCy Schubert  * Notes:
546*a466cc55SCy Schubert  *\li	This function is for debugging purposes only.
547*a466cc55SCy Schubert  *
548*a466cc55SCy Schubert  * Requires:
549*a466cc55SCy Schubert  *\li	'task' is a valid task.
550*a466cc55SCy Schubert  *
551*a466cc55SCy Schubert  * Returns:
552*a466cc55SCy Schubert  *\li	A non-NULL pointer to a null-terminated string.
553*a466cc55SCy Schubert  * 	If the task has not been named, the string is
554*a466cc55SCy Schubert  * 	empty.
555*a466cc55SCy Schubert  *
556*a466cc55SCy Schubert  */
557*a466cc55SCy Schubert 
558*a466cc55SCy Schubert void *
559*a466cc55SCy Schubert isc_task_gettag(isc_task_t *task);
560*a466cc55SCy Schubert /*%<
561*a466cc55SCy Schubert  * Get the tag value for  'task', as previously set using isc_task_settag().
562*a466cc55SCy Schubert  *
563*a466cc55SCy Schubert  * Notes:
564*a466cc55SCy Schubert  *\li	This function is for debugging purposes only.
565*a466cc55SCy Schubert  *
566*a466cc55SCy Schubert  * Requires:
567*a466cc55SCy Schubert  *\li	'task' is a valid task.
568*a466cc55SCy Schubert  */
569*a466cc55SCy Schubert 
570*a466cc55SCy Schubert isc_result_t
571*a466cc55SCy Schubert isc_task_beginexclusive(isc_task_t *task);
572*a466cc55SCy Schubert /*%<
573*a466cc55SCy Schubert  * Request exclusive access for 'task', which must be the calling
574*a466cc55SCy Schubert  * task.  Waits for any other concurrently executing tasks to finish their
575*a466cc55SCy Schubert  * current event, and prevents any new events from executing in any of the
576*a466cc55SCy Schubert  * tasks sharing a task manager with 'task'.
577*a466cc55SCy Schubert  *
578*a466cc55SCy Schubert  * The exclusive access must be relinquished by calling
579*a466cc55SCy Schubert  * isc_task_endexclusive() before returning from the current event handler.
580*a466cc55SCy Schubert  *
581*a466cc55SCy Schubert  * Requires:
582*a466cc55SCy Schubert  *\li	'task' is the calling task.
583*a466cc55SCy Schubert  *
584*a466cc55SCy Schubert  * Returns:
585*a466cc55SCy Schubert  *\li	#ISC_R_SUCCESS		The current task now has exclusive access.
586*a466cc55SCy Schubert  *\li	#ISC_R_LOCKBUSY		Another task has already requested exclusive
587*a466cc55SCy Schubert  *				access.
588*a466cc55SCy Schubert  */
589*a466cc55SCy Schubert 
590*a466cc55SCy Schubert void
591*a466cc55SCy Schubert isc_task_endexclusive(isc_task_t *task);
592*a466cc55SCy Schubert /*%<
593*a466cc55SCy Schubert  * Relinquish the exclusive access obtained by isc_task_beginexclusive(),
594*a466cc55SCy Schubert  * allowing other tasks to execute.
595*a466cc55SCy Schubert  *
596*a466cc55SCy Schubert  * Requires:
597*a466cc55SCy Schubert  *\li	'task' is the calling task, and has obtained
598*a466cc55SCy Schubert  *		exclusive access by calling isc_task_spl().
599*a466cc55SCy Schubert  */
600*a466cc55SCy Schubert 
601*a466cc55SCy Schubert void
602*a466cc55SCy Schubert isc_task_getcurrenttime(isc_task_t *task, isc_stdtime_t *t);
603*a466cc55SCy Schubert /*%<
604*a466cc55SCy Schubert  * Provide the most recent timestamp on the task.  The timestamp is considered
605*a466cc55SCy Schubert  * as the "current time" in the second-order granularity.
606*a466cc55SCy Schubert  *
607*a466cc55SCy Schubert  * Requires:
608*a466cc55SCy Schubert  *\li	'task' is a valid task.
609*a466cc55SCy Schubert  *\li	't' is a valid non NULL pointer.
610*a466cc55SCy Schubert  *
611*a466cc55SCy Schubert  * Ensures:
612*a466cc55SCy Schubert  *\li	'*t' has the "current time".
613*a466cc55SCy Schubert  */
614*a466cc55SCy Schubert 
615*a466cc55SCy Schubert isc_boolean_t
616*a466cc55SCy Schubert isc_task_exiting(isc_task_t *t);
617*a466cc55SCy Schubert /*%<
618*a466cc55SCy Schubert  * Returns ISC_TRUE if the task is in the process of shutting down,
619*a466cc55SCy Schubert  * ISC_FALSE otherwise.
620*a466cc55SCy Schubert  *
621*a466cc55SCy Schubert  * Requires:
622*a466cc55SCy Schubert  *\li	'task' is a valid task.
623*a466cc55SCy Schubert  */
624*a466cc55SCy Schubert 
625*a466cc55SCy Schubert void
626*a466cc55SCy Schubert isc_task_setprivilege(isc_task_t *task, isc_boolean_t priv);
627*a466cc55SCy Schubert /*%<
628*a466cc55SCy Schubert  * Set or unset the task's "privileged" flag depending on the value of
629*a466cc55SCy Schubert  * 'priv'.
630*a466cc55SCy Schubert  *
631*a466cc55SCy Schubert  * Under normal circumstances this flag has no effect on the task behavior,
632*a466cc55SCy Schubert  * but when the task manager has been set to privileged exeuction mode via
633*a466cc55SCy Schubert  * isc_taskmgr_setmode(), only tasks with the flag set will be executed,
634*a466cc55SCy Schubert  * and all other tasks will wait until they're done.  Once all privileged
635*a466cc55SCy Schubert  * tasks have finished executing, the task manager will automatically
636*a466cc55SCy Schubert  * return to normal execution mode and nonprivileged task can resume.
637*a466cc55SCy Schubert  *
638*a466cc55SCy Schubert  * Requires:
639*a466cc55SCy Schubert  *\li	'task' is a valid task.
640*a466cc55SCy Schubert  */
641*a466cc55SCy Schubert 
642*a466cc55SCy Schubert isc_boolean_t
643*a466cc55SCy Schubert isc_task_privilege(isc_task_t *task);
644*a466cc55SCy Schubert /*%<
645*a466cc55SCy Schubert  * Returns the current value of the task's privilege flag.
646*a466cc55SCy Schubert  *
647*a466cc55SCy Schubert  * Requires:
648*a466cc55SCy Schubert  *\li	'task' is a valid task.
649*a466cc55SCy Schubert  */
650*a466cc55SCy Schubert 
651*a466cc55SCy Schubert /*****
652*a466cc55SCy Schubert  ***** Task Manager.
653*a466cc55SCy Schubert  *****/
654*a466cc55SCy Schubert 
655*a466cc55SCy Schubert isc_result_t
656*a466cc55SCy Schubert isc_taskmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
657*a466cc55SCy Schubert 			unsigned int workers, unsigned int default_quantum,
658*a466cc55SCy Schubert 			isc_taskmgr_t **managerp);
659*a466cc55SCy Schubert isc_result_t
660*a466cc55SCy Schubert isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
661*a466cc55SCy Schubert 		   unsigned int default_quantum, isc_taskmgr_t **managerp);
662*a466cc55SCy Schubert /*%<
663*a466cc55SCy Schubert  * Create a new task manager.  isc_taskmgr_createinctx() also associates
664*a466cc55SCy Schubert  * the new manager with the specified application context.
665*a466cc55SCy Schubert  *
666*a466cc55SCy Schubert  * Notes:
667*a466cc55SCy Schubert  *
668*a466cc55SCy Schubert  *\li	'workers' in the number of worker threads to create.  In general,
669*a466cc55SCy Schubert  *	the value should be close to the number of processors in the system.
670*a466cc55SCy Schubert  *	The 'workers' value is advisory only.  An attempt will be made to
671*a466cc55SCy Schubert  *	create 'workers' threads, but if at least one thread creation
672*a466cc55SCy Schubert  *	succeeds, isc_taskmgr_create() may return ISC_R_SUCCESS.
673*a466cc55SCy Schubert  *
674*a466cc55SCy Schubert  *\li	If 'default_quantum' is non-zero, then it will be used as the default
675*a466cc55SCy Schubert  *	quantum value when tasks are created.  If zero, then an implementation
676*a466cc55SCy Schubert  *	defined default quantum will be used.
677*a466cc55SCy Schubert  *
678*a466cc55SCy Schubert  * Requires:
679*a466cc55SCy Schubert  *
680*a466cc55SCy Schubert  *\li      'mctx' is a valid memory context.
681*a466cc55SCy Schubert  *
682*a466cc55SCy Schubert  *\li	workers > 0
683*a466cc55SCy Schubert  *
684*a466cc55SCy Schubert  *\li	managerp != NULL && *managerp == NULL
685*a466cc55SCy Schubert  *
686*a466cc55SCy Schubert  *\li	'actx' is a valid application context (for createinctx()).
687*a466cc55SCy Schubert  *
688*a466cc55SCy Schubert  * Ensures:
689*a466cc55SCy Schubert  *
690*a466cc55SCy Schubert  *\li	On success, '*managerp' will be attached to the newly created task
691*a466cc55SCy Schubert  *	manager.
692*a466cc55SCy Schubert  *
693*a466cc55SCy Schubert  * Returns:
694*a466cc55SCy Schubert  *
695*a466cc55SCy Schubert  *\li	#ISC_R_SUCCESS
696*a466cc55SCy Schubert  *\li	#ISC_R_NOMEMORY
697*a466cc55SCy Schubert  *\li	#ISC_R_NOTHREADS		No threads could be created.
698*a466cc55SCy Schubert  *\li	#ISC_R_UNEXPECTED		An unexpected error occurred.
699*a466cc55SCy Schubert  *\li	#ISC_R_SHUTTINGDOWN      	The non-threaded, shared, task
700*a466cc55SCy Schubert  *					manager shutting down.
701*a466cc55SCy Schubert  */
702*a466cc55SCy Schubert 
703*a466cc55SCy Schubert void
704*a466cc55SCy Schubert isc_taskmgr_setmode(isc_taskmgr_t *manager, isc_taskmgrmode_t mode);
705*a466cc55SCy Schubert 
706*a466cc55SCy Schubert isc_taskmgrmode_t
707*a466cc55SCy Schubert isc_taskmgr_mode(isc_taskmgr_t *manager);
708*a466cc55SCy Schubert /*%<
709*a466cc55SCy Schubert  * Set/get the current operating mode of the task manager.  Valid modes are:
710*a466cc55SCy Schubert  *
711*a466cc55SCy Schubert  *\li  isc_taskmgrmode_normal
712*a466cc55SCy Schubert  *\li  isc_taskmgrmode_privileged
713*a466cc55SCy Schubert  *
714*a466cc55SCy Schubert  * In privileged execution mode, only tasks that have had the "privilege"
715*a466cc55SCy Schubert  * flag set via isc_task_setprivilege() can be executed.  When all such
716*a466cc55SCy Schubert  * tasks are complete, the manager automatically returns to normal mode
717*a466cc55SCy Schubert  * and proceeds with running non-privileged ready tasks.  This means it is
718*a466cc55SCy Schubert  * necessary to have at least one privileged task waiting on the ready
719*a466cc55SCy Schubert  * queue *before* setting the manager into privileged execution mode,
720*a466cc55SCy Schubert  * which in turn means the task which calls this function should be in
721*a466cc55SCy Schubert  * task-exclusive mode when it does so.
722*a466cc55SCy Schubert  *
723*a466cc55SCy Schubert  * Requires:
724*a466cc55SCy Schubert  *
725*a466cc55SCy Schubert  *\li      'manager' is a valid task manager.
726*a466cc55SCy Schubert  */
727*a466cc55SCy Schubert 
728*a466cc55SCy Schubert void
729*a466cc55SCy Schubert isc_taskmgr_destroy(isc_taskmgr_t **managerp);
730*a466cc55SCy Schubert /*%<
731*a466cc55SCy Schubert  * Destroy '*managerp'.
732*a466cc55SCy Schubert  *
733*a466cc55SCy Schubert  * Notes:
734*a466cc55SCy Schubert  *
735*a466cc55SCy Schubert  *\li	Calling isc_taskmgr_destroy() will shutdown all tasks managed by
736*a466cc55SCy Schubert  *	*managerp that haven't already been shutdown.  The call will block
737*a466cc55SCy Schubert  *	until all tasks have entered the done state.
738*a466cc55SCy Schubert  *
739*a466cc55SCy Schubert  *\li	isc_taskmgr_destroy() must not be called by a task event action,
740*a466cc55SCy Schubert  *	because it would block forever waiting for the event action to
741*a466cc55SCy Schubert  *	complete.  An event action that wants to cause task manager shutdown
742*a466cc55SCy Schubert  *	should request some non-event action thread of execution to do the
743*a466cc55SCy Schubert  *	shutdown, e.g. by signaling a condition variable or using
744*a466cc55SCy Schubert  *	isc_app_shutdown().
745*a466cc55SCy Schubert  *
746*a466cc55SCy Schubert  *\li	Task manager references are not reference counted, so the caller
747*a466cc55SCy Schubert  *	must ensure that no attempt will be made to use the manager after
748*a466cc55SCy Schubert  *	isc_taskmgr_destroy() returns.
749*a466cc55SCy Schubert  *
750*a466cc55SCy Schubert  * Requires:
751*a466cc55SCy Schubert  *
752*a466cc55SCy Schubert  *\li	'*managerp' is a valid task manager.
753*a466cc55SCy Schubert  *
754*a466cc55SCy Schubert  *\li	isc_taskmgr_destroy() has not be called previously on '*managerp'.
755*a466cc55SCy Schubert  *
756*a466cc55SCy Schubert  * Ensures:
757*a466cc55SCy Schubert  *
758*a466cc55SCy Schubert  *\li	All resources used by the task manager, and any tasks it managed,
759*a466cc55SCy Schubert  *	have been freed.
760*a466cc55SCy Schubert  */
761*a466cc55SCy Schubert 
762*a466cc55SCy Schubert #ifdef HAVE_LIBXML2
763*a466cc55SCy Schubert 
764*a466cc55SCy Schubert void
765*a466cc55SCy Schubert isc_taskmgr_renderxml(isc_taskmgr_t *mgr, xmlTextWriterPtr writer);
766*a466cc55SCy Schubert 
767*a466cc55SCy Schubert #endif
768*a466cc55SCy Schubert 
769*a466cc55SCy Schubert /*%<
770*a466cc55SCy Schubert  * See isc_taskmgr_create() above.
771*a466cc55SCy Schubert  */
772*a466cc55SCy Schubert typedef isc_result_t
773*a466cc55SCy Schubert (*isc_taskmgrcreatefunc_t)(isc_mem_t *mctx, unsigned int workers,
774*a466cc55SCy Schubert 			   unsigned int default_quantum,
775*a466cc55SCy Schubert 			   isc_taskmgr_t **managerp);
776*a466cc55SCy Schubert 
777*a466cc55SCy Schubert isc_result_t
778*a466cc55SCy Schubert isc_task_register(isc_taskmgrcreatefunc_t createfunc);
779*a466cc55SCy Schubert /*%<
780*a466cc55SCy Schubert  * Register a new task management implementation and add it to the list of
781*a466cc55SCy Schubert  * supported implementations.  This function must be called when a different
782*a466cc55SCy Schubert  * event library is used than the one contained in the ISC library.
783*a466cc55SCy Schubert  */
784*a466cc55SCy Schubert 
785*a466cc55SCy Schubert isc_result_t
786*a466cc55SCy Schubert isc__task_register(void);
787*a466cc55SCy Schubert /*%<
788*a466cc55SCy Schubert  * A short cut function that specifies the task management module in the ISC
789*a466cc55SCy Schubert  * library for isc_task_register().  An application that uses the ISC library
790*a466cc55SCy Schubert  * usually do not have to care about this function: it would call
791*a466cc55SCy Schubert  * isc_lib_register(), which internally calls this function.
792*a466cc55SCy Schubert  */
793*a466cc55SCy Schubert 
794*a466cc55SCy Schubert ISC_LANG_ENDDECLS
795*a466cc55SCy Schubert 
796*a466cc55SCy Schubert #endif /* ISC_TASK_H */
797