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