1290001Sglebius/* 2290001Sglebius * Copyright (C) 2009-2012 Internet Systems Consortium, Inc. ("ISC") 3290001Sglebius * 4290001Sglebius * Permission to use, copy, modify, and/or distribute this software for any 5290001Sglebius * purpose with or without fee is hereby granted, provided that the above 6290001Sglebius * copyright notice and this permission notice appear in all copies. 7290001Sglebius * 8290001Sglebius * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 9290001Sglebius * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10290001Sglebius * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 11290001Sglebius * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12290001Sglebius * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 13290001Sglebius * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14290001Sglebius * PERFORMANCE OF THIS SOFTWARE. 15290001Sglebius */ 16290001Sglebius 17290001Sglebius/* $Id$ */ 18290001Sglebius 19290001Sglebius#include <config.h> 20290001Sglebius 21290001Sglebius#include <unistd.h> 22290001Sglebius 23290001Sglebius#include <isc/app.h> 24290001Sglebius#include <isc/magic.h> 25290001Sglebius#include <isc/mutex.h> 26290001Sglebius#include <isc/once.h> 27290001Sglebius#include <isc/task.h> 28290001Sglebius#include <isc/util.h> 29290001Sglebius 30290001Sglebiusstatic isc_mutex_t createlock; 31290001Sglebiusstatic isc_once_t once = ISC_ONCE_INIT; 32290001Sglebiusstatic isc_taskmgrcreatefunc_t taskmgr_createfunc = NULL; 33290001Sglebius 34290001Sglebiusstatic void 35290001Sglebiusinitialize(void) { 36290001Sglebius RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS); 37290001Sglebius} 38290001Sglebius 39290001Sglebiusisc_result_t 40290001Sglebiusisc_task_register(isc_taskmgrcreatefunc_t createfunc) { 41290001Sglebius isc_result_t result = ISC_R_SUCCESS; 42290001Sglebius 43290001Sglebius RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); 44290001Sglebius 45290001Sglebius LOCK(&createlock); 46290001Sglebius if (taskmgr_createfunc == NULL) 47290001Sglebius taskmgr_createfunc = createfunc; 48290001Sglebius else 49290001Sglebius result = ISC_R_EXISTS; 50290001Sglebius UNLOCK(&createlock); 51290001Sglebius 52290001Sglebius return (result); 53290001Sglebius} 54290001Sglebius 55290001Sglebiusisc_result_t 56290001Sglebiusisc_taskmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx, 57290001Sglebius unsigned int workers, unsigned int default_quantum, 58290001Sglebius isc_taskmgr_t **managerp) 59290001Sglebius{ 60290001Sglebius isc_result_t result; 61290001Sglebius 62290001Sglebius LOCK(&createlock); 63290001Sglebius 64290001Sglebius REQUIRE(taskmgr_createfunc != NULL); 65290001Sglebius result = (*taskmgr_createfunc)(mctx, workers, default_quantum, 66290001Sglebius managerp); 67290001Sglebius 68290001Sglebius UNLOCK(&createlock); 69290001Sglebius 70290001Sglebius if (result == ISC_R_SUCCESS) 71290001Sglebius isc_appctx_settaskmgr(actx, *managerp); 72290001Sglebius 73290001Sglebius return (result); 74290001Sglebius} 75290001Sglebius 76290001Sglebiusisc_result_t 77290001Sglebiusisc_taskmgr_create(isc_mem_t *mctx, unsigned int workers, 78290001Sglebius unsigned int default_quantum, isc_taskmgr_t **managerp) 79290001Sglebius{ 80290001Sglebius isc_result_t result; 81290001Sglebius 82290001Sglebius LOCK(&createlock); 83290001Sglebius 84290001Sglebius REQUIRE(taskmgr_createfunc != NULL); 85290001Sglebius result = (*taskmgr_createfunc)(mctx, workers, default_quantum, 86290001Sglebius managerp); 87290001Sglebius 88290001Sglebius UNLOCK(&createlock); 89290001Sglebius 90290001Sglebius return (result); 91290001Sglebius} 92290001Sglebius 93290001Sglebiusvoid 94290001Sglebiusisc_taskmgr_destroy(isc_taskmgr_t **managerp) { 95290001Sglebius REQUIRE(managerp != NULL && ISCAPI_TASKMGR_VALID(*managerp)); 96290001Sglebius 97290001Sglebius (*managerp)->methods->destroy(managerp); 98290001Sglebius 99290001Sglebius ENSURE(*managerp == NULL); 100290001Sglebius} 101290001Sglebius 102290001Sglebiusvoid 103290001Sglebiusisc_taskmgr_setmode(isc_taskmgr_t *manager, isc_taskmgrmode_t mode) { 104290001Sglebius REQUIRE(ISCAPI_TASKMGR_VALID(manager)); 105290001Sglebius 106290001Sglebius manager->methods->setmode(manager, mode); 107290001Sglebius} 108290001Sglebius 109290001Sglebiusisc_taskmgrmode_t 110290001Sglebiusisc_taskmgr_mode(isc_taskmgr_t *manager) { 111290001Sglebius REQUIRE(ISCAPI_TASKMGR_VALID(manager)); 112290001Sglebius 113290001Sglebius return (manager->methods->mode(manager)); 114290001Sglebius} 115290001Sglebius 116290001Sglebiusisc_result_t 117290001Sglebiusisc_task_create(isc_taskmgr_t *manager, unsigned int quantum, 118290001Sglebius isc_task_t **taskp) 119290001Sglebius{ 120290001Sglebius REQUIRE(ISCAPI_TASKMGR_VALID(manager)); 121290001Sglebius REQUIRE(taskp != NULL && *taskp == NULL); 122290001Sglebius 123290001Sglebius return (manager->methods->taskcreate(manager, quantum, taskp)); 124290001Sglebius} 125290001Sglebius 126290001Sglebiusvoid 127290001Sglebiusisc_task_attach(isc_task_t *source, isc_task_t **targetp) { 128290001Sglebius REQUIRE(ISCAPI_TASK_VALID(source)); 129290001Sglebius REQUIRE(targetp != NULL && *targetp == NULL); 130290001Sglebius 131290001Sglebius source->methods->attach(source, targetp); 132290001Sglebius 133290001Sglebius ENSURE(*targetp == source); 134290001Sglebius} 135290001Sglebius 136290001Sglebiusvoid 137290001Sglebiusisc_task_detach(isc_task_t **taskp) { 138290001Sglebius REQUIRE(taskp != NULL && ISCAPI_TASK_VALID(*taskp)); 139290001Sglebius 140290001Sglebius (*taskp)->methods->detach(taskp); 141290001Sglebius 142290001Sglebius ENSURE(*taskp == NULL); 143290001Sglebius} 144290001Sglebius 145290001Sglebiusvoid 146290001Sglebiusisc_task_send(isc_task_t *task, isc_event_t **eventp) { 147290001Sglebius REQUIRE(ISCAPI_TASK_VALID(task)); 148290001Sglebius REQUIRE(eventp != NULL && *eventp != NULL); 149290001Sglebius 150290001Sglebius task->methods->send(task, eventp); 151290001Sglebius 152290001Sglebius ENSURE(*eventp == NULL); 153290001Sglebius} 154290001Sglebius 155290001Sglebiusvoid 156290001Sglebiusisc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) { 157290001Sglebius REQUIRE(taskp != NULL && ISCAPI_TASK_VALID(*taskp)); 158290001Sglebius REQUIRE(eventp != NULL && *eventp != NULL); 159290001Sglebius 160290001Sglebius (*taskp)->methods->sendanddetach(taskp, eventp); 161290001Sglebius 162290001Sglebius ENSURE(*taskp == NULL && *eventp == NULL); 163290001Sglebius} 164290001Sglebius 165290001Sglebiusunsigned int 166290001Sglebiusisc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type, 167290001Sglebius void *tag, isc_eventlist_t *events) 168290001Sglebius{ 169290001Sglebius REQUIRE(ISCAPI_TASK_VALID(task)); 170290001Sglebius 171290001Sglebius return (task->methods->unsend(task, sender, type, tag, events)); 172290001Sglebius} 173290001Sglebius 174290001Sglebiusisc_result_t 175290001Sglebiusisc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, const void *arg) 176290001Sglebius{ 177290001Sglebius REQUIRE(ISCAPI_TASK_VALID(task)); 178290001Sglebius 179290001Sglebius return (task->methods->onshutdown(task, action, arg)); 180290001Sglebius} 181290001Sglebius 182290001Sglebiusvoid 183290001Sglebiusisc_task_shutdown(isc_task_t *task) { 184290001Sglebius REQUIRE(ISCAPI_TASK_VALID(task)); 185290001Sglebius 186290001Sglebius task->methods->shutdown(task); 187290001Sglebius} 188290001Sglebius 189290001Sglebiusvoid 190290001Sglebiusisc_task_setname(isc_task_t *task, const char *name, void *tag) { 191290001Sglebius REQUIRE(ISCAPI_TASK_VALID(task)); 192290001Sglebius 193290001Sglebius task->methods->setname(task, name, tag); 194290001Sglebius} 195290001Sglebius 196290001Sglebiusunsigned int 197290001Sglebiusisc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag) 198290001Sglebius{ 199290001Sglebius REQUIRE(ISCAPI_TASK_VALID(task)); 200290001Sglebius 201290001Sglebius return (task->methods->purgeevents(task, sender, type, tag)); 202290001Sglebius} 203290001Sglebius 204290001Sglebiusisc_result_t 205290001Sglebiusisc_task_beginexclusive(isc_task_t *task) { 206290001Sglebius REQUIRE(ISCAPI_TASK_VALID(task)); 207290001Sglebius 208290001Sglebius return (task->methods->beginexclusive(task)); 209290001Sglebius} 210290001Sglebius 211290001Sglebiusvoid 212290001Sglebiusisc_task_endexclusive(isc_task_t *task) { 213290001Sglebius REQUIRE(ISCAPI_TASK_VALID(task)); 214290001Sglebius 215290001Sglebius task->methods->endexclusive(task); 216290001Sglebius} 217290001Sglebius 218290001Sglebiusvoid 219290001Sglebiusisc_task_setprivilege(isc_task_t *task, isc_boolean_t priv) { 220290001Sglebius REQUIRE(ISCAPI_TASK_VALID(task)); 221290001Sglebius 222290001Sglebius task->methods->setprivilege(task, priv); 223290001Sglebius} 224290001Sglebius 225290001Sglebiusisc_boolean_t 226290001Sglebiusisc_task_privilege(isc_task_t *task) { 227290001Sglebius REQUIRE(ISCAPI_TASK_VALID(task)); 228290001Sglebius 229290001Sglebius return (task->methods->privilege(task)); 230290001Sglebius} 231290001Sglebius 232290001Sglebius 233290001Sglebius/*% 234290001Sglebius * This is necessary for libisc's internal timer implementation. Other 235290001Sglebius * implementation might skip implementing this. 236290001Sglebius */ 237290001Sglebiusunsigned int 238290001Sglebiusisc_task_purgerange(isc_task_t *task, void *sender, isc_eventtype_t first, 239290001Sglebius isc_eventtype_t last, void *tag) 240290001Sglebius{ 241290001Sglebius REQUIRE(ISCAPI_TASK_VALID(task)); 242290001Sglebius 243290001Sglebius return (task->methods->purgerange(task, sender, first, last, tag)); 244290001Sglebius} 245