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