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