/contrib/bind9/lib/isc/task_api.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 216 lines · 141 code · 55 blank · 20 comment · 33 complexity · 619143ff3959213ea5ddc55d1e0160f8 MD5 · raw file

  1. /*
  2. * Copyright (C) 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC")
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  9. * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  10. * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  11. * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  12. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  13. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  14. * PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. /* $Id$ */
  17. #include <config.h>
  18. #include <unistd.h>
  19. #include <isc/app.h>
  20. #include <isc/magic.h>
  21. #include <isc/mutex.h>
  22. #include <isc/once.h>
  23. #include <isc/task.h>
  24. #include <isc/util.h>
  25. static isc_mutex_t createlock;
  26. static isc_once_t once = ISC_ONCE_INIT;
  27. static isc_taskmgrcreatefunc_t taskmgr_createfunc = NULL;
  28. static void
  29. initialize(void) {
  30. RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS);
  31. }
  32. isc_result_t
  33. isc_task_register(isc_taskmgrcreatefunc_t createfunc) {
  34. isc_result_t result = ISC_R_SUCCESS;
  35. RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
  36. LOCK(&createlock);
  37. if (taskmgr_createfunc == NULL)
  38. taskmgr_createfunc = createfunc;
  39. else
  40. result = ISC_R_EXISTS;
  41. UNLOCK(&createlock);
  42. return (result);
  43. }
  44. isc_result_t
  45. isc_taskmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
  46. unsigned int workers, unsigned int default_quantum,
  47. isc_taskmgr_t **managerp)
  48. {
  49. isc_result_t result;
  50. LOCK(&createlock);
  51. REQUIRE(taskmgr_createfunc != NULL);
  52. result = (*taskmgr_createfunc)(mctx, workers, default_quantum,
  53. managerp);
  54. UNLOCK(&createlock);
  55. if (result == ISC_R_SUCCESS)
  56. isc_appctx_settaskmgr(actx, *managerp);
  57. return (result);
  58. }
  59. isc_result_t
  60. isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
  61. unsigned int default_quantum, isc_taskmgr_t **managerp)
  62. {
  63. isc_result_t result;
  64. LOCK(&createlock);
  65. REQUIRE(taskmgr_createfunc != NULL);
  66. result = (*taskmgr_createfunc)(mctx, workers, default_quantum,
  67. managerp);
  68. UNLOCK(&createlock);
  69. return (result);
  70. }
  71. void
  72. isc_taskmgr_destroy(isc_taskmgr_t **managerp) {
  73. REQUIRE(managerp != NULL && ISCAPI_TASKMGR_VALID(*managerp));
  74. (*managerp)->methods->destroy(managerp);
  75. ENSURE(*managerp == NULL);
  76. }
  77. isc_result_t
  78. isc_task_create(isc_taskmgr_t *manager, unsigned int quantum,
  79. isc_task_t **taskp)
  80. {
  81. REQUIRE(ISCAPI_TASKMGR_VALID(manager));
  82. REQUIRE(taskp != NULL && *taskp == NULL);
  83. return (manager->methods->taskcreate(manager, quantum, taskp));
  84. }
  85. void
  86. isc_task_attach(isc_task_t *source, isc_task_t **targetp) {
  87. REQUIRE(ISCAPI_TASK_VALID(source));
  88. REQUIRE(targetp != NULL && *targetp == NULL);
  89. source->methods->attach(source, targetp);
  90. ENSURE(*targetp == source);
  91. }
  92. void
  93. isc_task_detach(isc_task_t **taskp) {
  94. REQUIRE(taskp != NULL && ISCAPI_TASK_VALID(*taskp));
  95. (*taskp)->methods->detach(taskp);
  96. ENSURE(*taskp == NULL);
  97. }
  98. void
  99. isc_task_send(isc_task_t *task, isc_event_t **eventp) {
  100. REQUIRE(ISCAPI_TASK_VALID(task));
  101. REQUIRE(eventp != NULL && *eventp != NULL);
  102. task->methods->send(task, eventp);
  103. ENSURE(*eventp == NULL);
  104. }
  105. void
  106. isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) {
  107. REQUIRE(taskp != NULL && ISCAPI_TASK_VALID(*taskp));
  108. REQUIRE(eventp != NULL && *eventp != NULL);
  109. (*taskp)->methods->sendanddetach(taskp, eventp);
  110. ENSURE(*taskp == NULL && *eventp == NULL);
  111. }
  112. unsigned int
  113. isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
  114. void *tag, isc_eventlist_t *events)
  115. {
  116. REQUIRE(ISCAPI_TASK_VALID(task));
  117. return (task->methods->unsend(task, sender, type, tag, events));
  118. }
  119. isc_result_t
  120. isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, const void *arg)
  121. {
  122. REQUIRE(ISCAPI_TASK_VALID(task));
  123. return (task->methods->onshutdown(task, action, arg));
  124. }
  125. void
  126. isc_task_shutdown(isc_task_t *task) {
  127. REQUIRE(ISCAPI_TASK_VALID(task));
  128. task->methods->shutdown(task);
  129. }
  130. void
  131. isc_task_setname(isc_task_t *task, const char *name, void *tag) {
  132. REQUIRE(ISCAPI_TASK_VALID(task));
  133. task->methods->setname(task, name, tag);
  134. }
  135. unsigned int
  136. isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag)
  137. {
  138. REQUIRE(ISCAPI_TASK_VALID(task));
  139. return (task->methods->purgeevents(task, sender, type, tag));
  140. }
  141. isc_result_t
  142. isc_task_beginexclusive(isc_task_t *task) {
  143. REQUIRE(ISCAPI_TASK_VALID(task));
  144. return (task->methods->beginexclusive(task));
  145. }
  146. void
  147. isc_task_endexclusive(isc_task_t *task) {
  148. REQUIRE(ISCAPI_TASK_VALID(task));
  149. task->methods->endexclusive(task);
  150. }
  151. /*%
  152. * This is necessary for libisc's internal timer implementation. Other
  153. * implementation might skip implementing this.
  154. */
  155. unsigned int
  156. isc_task_purgerange(isc_task_t *task, void *sender, isc_eventtype_t first,
  157. isc_eventtype_t last, void *tag)
  158. {
  159. REQUIRE(ISCAPI_TASK_VALID(task));
  160. return (task->methods->purgerange(task, sender, first, last, tag));
  161. }