Import bind 9.5.2 vendor sources.
[dragonfly.git] / contrib / bind-9.5.2 / lib / isc / include / isc / task.h
1 /*
2  * Copyright (C) 2004-2007, 2009  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: task.h,v 1.61.128.2 2009/01/19 23:47:03 tbox Exp $ */
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 isc_result_t
100 isc_task_create(isc_taskmgr_t *manager, unsigned int quantum,
101                 isc_task_t **taskp);
102 /*%<
103  * Create a task.
104  *
105  * Notes:
106  *
107  *\li   If 'quantum' is non-zero, then only that many events can be dispatched
108  *      before the task must yield to other tasks waiting to execute.  If
109  *      quantum is zero, then the default quantum of the task manager will
110  *      be used.
111  *
112  *\li   The 'quantum' option may be removed from isc_task_create() in the
113  *      future.  If this happens, isc_task_getquantum() and
114  *      isc_task_setquantum() will be provided.
115  *
116  * Requires:
117  *
118  *\li   'manager' is a valid task manager.
119  *
120  *\li   taskp != NULL && *taskp == NULL
121  *
122  * Ensures:
123  *
124  *\li   On success, '*taskp' is bound to the new task.
125  *
126  * Returns:
127  *
128  *\li   #ISC_R_SUCCESS
129  *\li   #ISC_R_NOMEMORY
130  *\li   #ISC_R_UNEXPECTED
131  *\li   #ISC_R_SHUTTINGDOWN
132  */
133
134 void
135 isc_task_attach(isc_task_t *source, isc_task_t **targetp);
136 /*%<
137  * Attach *targetp to source.
138  *
139  * Requires:
140  *
141  *\li   'source' is a valid task.
142  *
143  *\li   'targetp' points to a NULL isc_task_t *.
144  *
145  * Ensures:
146  *
147  *\li   *targetp is attached to source.
148  */
149
150 void
151 isc_task_detach(isc_task_t **taskp);
152 /*%<
153  * Detach *taskp from its task.
154  *
155  * Requires:
156  *
157  *\li   '*taskp' is a valid task.
158  *
159  * Ensures:
160  *
161  *\li   *taskp is NULL.
162  *
163  *\li   If '*taskp' is the last reference to the task, the task is idle (has
164  *      an empty event queue), and has not been shutdown, the task will be
165  *      shutdown.
166  *
167  *\li   If '*taskp' is the last reference to the task and
168  *      the task has been shutdown,
169  *              all resources used by the task will be freed.
170  */
171
172 void
173 isc_task_send(isc_task_t *task, isc_event_t **eventp);
174 /*%<
175  * Send '*event' to 'task'.
176  *
177  * Requires:
178  *
179  *\li   'task' is a valid task.
180  *\li   eventp != NULL && *eventp != NULL.
181  *
182  * Ensures:
183  *
184  *\li   *eventp == NULL.
185  */
186
187 void
188 isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp);
189 /*%<
190  * Send '*event' to '*taskp' and then detach '*taskp' from its
191  * task.
192  *
193  * Requires:
194  *
195  *\li   '*taskp' is a valid task.
196  *\li   eventp != NULL && *eventp != NULL.
197  *
198  * Ensures:
199  *
200  *\li   *eventp == NULL.
201  *
202  *\li   *taskp == NULL.
203  *
204  *\li   If '*taskp' is the last reference to the task, the task is
205  *      idle (has an empty event queue), and has not been shutdown,
206  *      the task will be shutdown.
207  *
208  *\li   If '*taskp' is the last reference to the task and
209  *      the task has been shutdown,
210  *              all resources used by the task will be freed.
211  */
212
213
214 unsigned int
215 isc_task_purgerange(isc_task_t *task, void *sender, isc_eventtype_t first,
216                     isc_eventtype_t last, void *tag);
217 /*%<
218  * Purge events from a task's event queue.
219  *
220  * Requires:
221  *
222  *\li   'task' is a valid task.
223  *
224  *\li   last >= first
225  *
226  * Ensures:
227  *
228  *\li   Events in the event queue of 'task' whose sender is 'sender', whose
229  *      type is >= first and <= last, and whose tag is 'tag' will be purged,
230  *      unless they are marked as unpurgable.
231  *
232  *\li   A sender of NULL will match any sender.  A NULL tag matches any
233  *      tag.
234  *
235  * Returns:
236  *
237  *\li   The number of events purged.
238  */
239
240 unsigned int
241 isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type,
242                void *tag);
243 /*%<
244  * Purge events from a task's event queue.
245  *
246  * Notes:
247  *
248  *\li   This function is equivalent to
249  *
250  *\code
251  *              isc_task_purgerange(task, sender, type, type, tag);
252  *\endcode
253  *
254  * Requires:
255  *
256  *\li   'task' is a valid task.
257  *
258  * Ensures:
259  *
260  *\li   Events in the event queue of 'task' whose sender is 'sender', whose
261  *      type is 'type', and whose tag is 'tag' will be purged, unless they
262  *      are marked as unpurgable.
263  *
264  *\li   A sender of NULL will match any sender.  A NULL tag matches any
265  *      tag.
266  *
267  * Returns:
268  *
269  *\li   The number of events purged.
270  */
271
272 isc_boolean_t
273 isc_task_purgeevent(isc_task_t *task, isc_event_t *event);
274 /*%<
275  * Purge 'event' from a task's event queue.
276  *
277  * XXXRTH:  WARNING:  This method may be removed before beta.
278  *
279  * Notes:
280  *
281  *\li   If 'event' is on the task's event queue, it will be purged,
282  *      unless it is marked as unpurgeable.  'event' does not have to be
283  *      on the task's event queue; in fact, it can even be an invalid
284  *      pointer.  Purging only occurs if the event is actually on the task's
285  *      event queue.
286  *
287  * \li  Purging never changes the state of the task.
288  *
289  * Requires:
290  *
291  *\li   'task' is a valid task.
292  *
293  * Ensures:
294  *
295  *\li   'event' is not in the event queue for 'task'.
296  *
297  * Returns:
298  *
299  *\li   #ISC_TRUE                       The event was purged.
300  *\li   #ISC_FALSE                      The event was not in the event queue,
301  *                                      or was marked unpurgeable.
302  */
303
304 unsigned int
305 isc_task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first,
306                      isc_eventtype_t last, void *tag, isc_eventlist_t *events);
307 /*%<
308  * Remove events from a task's event queue.
309  *
310  * Requires:
311  *
312  *\li   'task' is a valid task.
313  *
314  *\li   last >= first.
315  *
316  *\li   *events is a valid list.
317  *
318  * Ensures:
319  *
320  *\li   Events in the event queue of 'task' whose sender is 'sender', whose
321  *      type is >= first and <= last, and whose tag is 'tag' will be dequeued
322  *      and appended to *events.
323  *
324  *\li   A sender of NULL will match any sender.  A NULL tag matches any
325  *      tag.
326  *
327  * Returns:
328  *
329  *\li   The number of events unsent.
330  */
331
332 unsigned int
333 isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
334                 void *tag, isc_eventlist_t *events);
335 /*%<
336  * Remove events from a task's event queue.
337  *
338  * Notes:
339  *
340  *\li   This function is equivalent to
341  *
342  *\code
343  *              isc_task_unsendrange(task, sender, type, type, tag, events);
344  *\endcode
345  *
346  * Requires:
347  *
348  *\li   'task' is a valid task.
349  *
350  *\li   *events is a valid list.
351  *
352  * Ensures:
353  *
354  *\li   Events in the event queue of 'task' whose sender is 'sender', whose
355  *      type is 'type', and whose tag is 'tag' will be dequeued and appended
356  *      to *events.
357  *
358  * Returns:
359  *
360  *\li   The number of events unsent.
361  */
362
363 isc_result_t
364 isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action,
365                     const void *arg);
366 /*%<
367  * Send a shutdown event with action 'action' and argument 'arg' when
368  * 'task' is shutdown.
369  *
370  * Notes:
371  *
372  *\li   Shutdown events are posted in LIFO order.
373  *
374  * Requires:
375  *
376  *\li   'task' is a valid task.
377  *
378  *\li   'action' is a valid task action.
379  *
380  * Ensures:
381  *
382  *\li   When the task is shutdown, shutdown events requested with
383  *      isc_task_onshutdown() will be appended to the task's event queue.
384  *
385
386  * Returns:
387  *
388  *\li   #ISC_R_SUCCESS
389  *\li   #ISC_R_NOMEMORY
390  *\li   #ISC_R_TASKSHUTTINGDOWN                 Task is shutting down.
391  */
392
393 void
394 isc_task_shutdown(isc_task_t *task);
395 /*%<
396  * Shutdown 'task'.
397  *
398  * Notes:
399  *
400  *\li   Shutting down a task causes any shutdown events requested with
401  *      isc_task_onshutdown() to be posted (in LIFO order).  The task
402  *      moves into a "shutting down" mode which prevents further calls
403  *      to isc_task_onshutdown().
404  *
405  *\li   Trying to shutdown a task that has already been shutdown has no
406  *      effect.
407  *
408  * Requires:
409  *
410  *\li   'task' is a valid task.
411  *
412  * Ensures:
413  *
414  *\li   Any shutdown events requested with isc_task_onshutdown() have been
415  *      posted (in LIFO order).
416  */
417
418 void
419 isc_task_destroy(isc_task_t **taskp);
420 /*%<
421  * Destroy '*taskp'.
422  *
423  * Notes:
424  *
425  *\li   This call is equivalent to:
426  *
427  *\code
428  *              isc_task_shutdown(*taskp);
429  *              isc_task_detach(taskp);
430  *\endcode
431  *
432  * Requires:
433  *
434  *      '*taskp' is a valid task.
435  *
436  * Ensures:
437  *
438  *\li   Any shutdown events requested with isc_task_onshutdown() have been
439  *      posted (in LIFO order).
440  *
441  *\li   *taskp == NULL
442  *
443  *\li   If '*taskp' is the last reference to the task,
444  *              all resources used by the task will be freed.
445  */
446
447 void
448 isc_task_setname(isc_task_t *task, const char *name, void *tag);
449 /*%<
450  * Name 'task'.
451  *
452  * Notes:
453  *
454  *\li   Only the first 15 characters of 'name' will be copied.
455  *
456  *\li   Naming a task is currently only useful for debugging purposes.
457  *
458  * Requires:
459  *
460  *\li   'task' is a valid task.
461  */
462
463 const char *
464 isc_task_getname(isc_task_t *task);
465 /*%<
466  * Get the name of 'task', as previously set using isc_task_setname().
467  *
468  * Notes:
469  *\li   This function is for debugging purposes only.
470  *
471  * Requires:
472  *\li   'task' is a valid task.
473  *
474  * Returns:
475  *\li   A non-NULL pointer to a null-terminated string.
476  *      If the task has not been named, the string is
477  *      empty.
478  *
479  */
480
481 void *
482 isc_task_gettag(isc_task_t *task);
483 /*%<
484  * Get the tag value for  'task', as previously set using isc_task_settag().
485  *
486  * Notes:
487  *\li   This function is for debugging purposes only.
488  *
489  * Requires:
490  *\li   'task' is a valid task.
491  */
492
493 isc_result_t
494 isc_task_beginexclusive(isc_task_t *task);
495 /*%<
496  * Request exclusive access for 'task', which must be the calling
497  * task.  Waits for any other concurrently executing tasks to finish their
498  * current event, and prevents any new events from executing in any of the
499  * tasks sharing a task manager with 'task'.
500  *
501  * The exclusive access must be relinquished by calling
502  * isc_task_endexclusive() before returning from the current event handler.
503  *
504  * Requires:
505  *\li   'task' is the calling task.
506  *
507  * Returns:
508  *\li   #ISC_R_SUCCESS          The current task now has exclusive access.
509  *\li   #ISC_R_LOCKBUSY         Another task has already requested exclusive
510  *                              access.
511  */
512
513 void
514 isc_task_endexclusive(isc_task_t *task);
515 /*%<
516  * Relinquish the exclusive access obtained by isc_task_beginexclusive(),
517  * allowing other tasks to execute.
518  *
519  * Requires:
520  *\li   'task' is the calling task, and has obtained
521  *              exclusive access by calling isc_task_spl().
522  */
523
524 void
525 isc_task_getcurrenttime(isc_task_t *task, isc_stdtime_t *t);
526 /*%<
527  * Provide the most recent timestamp on the task.  The timestamp is considered
528  * as the "current time" in the second-order granularity.
529  *
530  * Requires:
531  *\li   'task' is a valid task.
532  *\li   't' is a valid non NULL pointer.
533  *
534  * Ensures:
535  *\li   '*t' has the "current time".
536  */
537
538 /*****
539  ***** Task Manager.
540  *****/
541
542 isc_result_t
543 isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
544                    unsigned int default_quantum, isc_taskmgr_t **managerp);
545 /*%<
546  * Create a new task manager.
547  *
548  * Notes:
549  *
550  *\li   'workers' in the number of worker threads to create.  In general,
551  *      the value should be close to the number of processors in the system.
552  *      The 'workers' value is advisory only.  An attempt will be made to
553  *      create 'workers' threads, but if at least one thread creation
554  *      succeeds, isc_taskmgr_create() may return ISC_R_SUCCESS.
555  *
556  *\li   If 'default_quantum' is non-zero, then it will be used as the default
557  *      quantum value when tasks are created.  If zero, then an implementation
558  *      defined default quantum will be used.
559  *
560  * Requires:
561  *
562  *\li      'mctx' is a valid memory context.
563  *
564  *\li   workers > 0
565  *
566  *\li   managerp != NULL && *managerp == NULL
567  *
568  * Ensures:
569  *
570  *\li   On success, '*managerp' will be attached to the newly created task
571  *      manager.
572  *
573  * Returns:
574  *
575  *\li   #ISC_R_SUCCESS
576  *\li   #ISC_R_NOMEMORY
577  *\li   #ISC_R_NOTHREADS                        No threads could be created.
578  *\li   #ISC_R_UNEXPECTED               An unexpected error occurred.
579  */
580
581 void
582 isc_taskmgr_destroy(isc_taskmgr_t **managerp);
583 /*%<
584  * Destroy '*managerp'.
585  *
586  * Notes:
587  *
588  *\li   Calling isc_taskmgr_destroy() will shutdown all tasks managed by
589  *      *managerp that haven't already been shutdown.  The call will block
590  *      until all tasks have entered the done state.
591  *
592  *\li   isc_taskmgr_destroy() must not be called by a task event action,
593  *      because it would block forever waiting for the event action to
594  *      complete.  An event action that wants to cause task manager shutdown
595  *      should request some non-event action thread of execution to do the
596  *      shutdown, e.g. by signaling a condition variable or using
597  *      isc_app_shutdown().
598  *
599  *\li   Task manager references are not reference counted, so the caller
600  *      must ensure that no attempt will be made to use the manager after
601  *      isc_taskmgr_destroy() returns.
602  *
603  * Requires:
604  *
605  *\li   '*managerp' is a valid task manager.
606  *
607  *\li   isc_taskmgr_destroy() has not be called previously on '*managerp'.
608  *
609  * Ensures:
610  *
611  *\li   All resources used by the task manager, and any tasks it managed,
612  *      have been freed.
613  */
614
615 #ifdef HAVE_LIBXML2
616
617 void
618 isc_taskmgr_renderxml(isc_taskmgr_t *mgr, xmlTextWriterPtr writer);
619
620 #endif
621
622 ISC_LANG_ENDDECLS
623
624 #endif /* ISC_TASK_H */