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