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