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