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