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