1224090Sdougb/* 2254897Serwin * Copyright (C) 2009-2012 Internet Systems Consortium, Inc. ("ISC") 3224090Sdougb * 4224090Sdougb * Permission to use, copy, modify, and/or distribute this software for any 5224090Sdougb * purpose with or without fee is hereby granted, provided that the above 6224090Sdougb * copyright notice and this permission notice appear in all copies. 7224090Sdougb * 8224090Sdougb * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 9224090Sdougb * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10224090Sdougb * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 11224090Sdougb * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12224090Sdougb * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 13224090Sdougb * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14224090Sdougb * PERFORMANCE OF THIS SOFTWARE. 15224090Sdougb */ 16224090Sdougb 17234010Sdougb/* $Id$ */ 18224090Sdougb 19224090Sdougb#include <config.h> 20224090Sdougb 21224090Sdougb#include <unistd.h> 22224090Sdougb 23224090Sdougb#include <isc/app.h> 24224090Sdougb#include <isc/magic.h> 25224090Sdougb#include <isc/mutex.h> 26224090Sdougb#include <isc/once.h> 27224090Sdougb#include <isc/task.h> 28224090Sdougb#include <isc/util.h> 29224090Sdougb 30224090Sdougbstatic isc_mutex_t createlock; 31224090Sdougbstatic isc_once_t once = ISC_ONCE_INIT; 32224090Sdougbstatic isc_taskmgrcreatefunc_t taskmgr_createfunc = NULL; 33224090Sdougb 34224090Sdougbstatic void 35224090Sdougbinitialize(void) { 36224090Sdougb RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS); 37224090Sdougb} 38224090Sdougb 39224090Sdougbisc_result_t 40224090Sdougbisc_task_register(isc_taskmgrcreatefunc_t createfunc) { 41224090Sdougb isc_result_t result = ISC_R_SUCCESS; 42224090Sdougb 43224090Sdougb RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); 44224090Sdougb 45224090Sdougb LOCK(&createlock); 46224090Sdougb if (taskmgr_createfunc == NULL) 47224090Sdougb taskmgr_createfunc = createfunc; 48224090Sdougb else 49224090Sdougb result = ISC_R_EXISTS; 50224090Sdougb UNLOCK(&createlock); 51224090Sdougb 52224090Sdougb return (result); 53224090Sdougb} 54224090Sdougb 55224090Sdougbisc_result_t 56224090Sdougbisc_taskmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx, 57224090Sdougb unsigned int workers, unsigned int default_quantum, 58224090Sdougb isc_taskmgr_t **managerp) 59224090Sdougb{ 60224090Sdougb isc_result_t result; 61224090Sdougb 62224090Sdougb LOCK(&createlock); 63224090Sdougb 64224090Sdougb REQUIRE(taskmgr_createfunc != NULL); 65224090Sdougb result = (*taskmgr_createfunc)(mctx, workers, default_quantum, 66224090Sdougb managerp); 67224090Sdougb 68224090Sdougb UNLOCK(&createlock); 69224090Sdougb 70224090Sdougb if (result == ISC_R_SUCCESS) 71224090Sdougb isc_appctx_settaskmgr(actx, *managerp); 72224090Sdougb 73224090Sdougb return (result); 74224090Sdougb} 75224090Sdougb 76224090Sdougbisc_result_t 77224090Sdougbisc_taskmgr_create(isc_mem_t *mctx, unsigned int workers, 78224090Sdougb unsigned int default_quantum, isc_taskmgr_t **managerp) 79224090Sdougb{ 80224090Sdougb isc_result_t result; 81224090Sdougb 82224090Sdougb LOCK(&createlock); 83224090Sdougb 84224090Sdougb REQUIRE(taskmgr_createfunc != NULL); 85224090Sdougb result = (*taskmgr_createfunc)(mctx, workers, default_quantum, 86224090Sdougb managerp); 87224090Sdougb 88224090Sdougb UNLOCK(&createlock); 89224090Sdougb 90224090Sdougb return (result); 91224090Sdougb} 92224090Sdougb 93224090Sdougbvoid 94224090Sdougbisc_taskmgr_destroy(isc_taskmgr_t **managerp) { 95224090Sdougb REQUIRE(managerp != NULL && ISCAPI_TASKMGR_VALID(*managerp)); 96224090Sdougb 97224090Sdougb (*managerp)->methods->destroy(managerp); 98224090Sdougb 99224090Sdougb ENSURE(*managerp == NULL); 100224090Sdougb} 101224090Sdougb 102254897Serwinvoid 103254897Serwinisc_taskmgr_setmode(isc_taskmgr_t *manager, isc_taskmgrmode_t mode) { 104254897Serwin REQUIRE(ISCAPI_TASKMGR_VALID(manager)); 105254897Serwin 106254897Serwin manager->methods->setmode(manager, mode); 107254897Serwin} 108254897Serwin 109254897Serwinisc_taskmgrmode_t 110254897Serwinisc_taskmgr_mode(isc_taskmgr_t *manager) { 111254897Serwin REQUIRE(ISCAPI_TASKMGR_VALID(manager)); 112254897Serwin 113254897Serwin return (manager->methods->mode(manager)); 114254897Serwin} 115254897Serwin 116224090Sdougbisc_result_t 117224090Sdougbisc_task_create(isc_taskmgr_t *manager, unsigned int quantum, 118224090Sdougb isc_task_t **taskp) 119224090Sdougb{ 120224090Sdougb REQUIRE(ISCAPI_TASKMGR_VALID(manager)); 121224090Sdougb REQUIRE(taskp != NULL && *taskp == NULL); 122224090Sdougb 123224090Sdougb return (manager->methods->taskcreate(manager, quantum, taskp)); 124224090Sdougb} 125224090Sdougb 126224090Sdougbvoid 127224090Sdougbisc_task_attach(isc_task_t *source, isc_task_t **targetp) { 128224090Sdougb REQUIRE(ISCAPI_TASK_VALID(source)); 129224090Sdougb REQUIRE(targetp != NULL && *targetp == NULL); 130224090Sdougb 131224090Sdougb source->methods->attach(source, targetp); 132224090Sdougb 133224090Sdougb ENSURE(*targetp == source); 134224090Sdougb} 135224090Sdougb 136224090Sdougbvoid 137224090Sdougbisc_task_detach(isc_task_t **taskp) { 138224090Sdougb REQUIRE(taskp != NULL && ISCAPI_TASK_VALID(*taskp)); 139224090Sdougb 140224090Sdougb (*taskp)->methods->detach(taskp); 141224090Sdougb 142224090Sdougb ENSURE(*taskp == NULL); 143224090Sdougb} 144224090Sdougb 145224090Sdougbvoid 146224090Sdougbisc_task_send(isc_task_t *task, isc_event_t **eventp) { 147224090Sdougb REQUIRE(ISCAPI_TASK_VALID(task)); 148224090Sdougb REQUIRE(eventp != NULL && *eventp != NULL); 149224090Sdougb 150224090Sdougb task->methods->send(task, eventp); 151224090Sdougb 152224090Sdougb ENSURE(*eventp == NULL); 153224090Sdougb} 154224090Sdougb 155224090Sdougbvoid 156224090Sdougbisc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) { 157224090Sdougb REQUIRE(taskp != NULL && ISCAPI_TASK_VALID(*taskp)); 158224090Sdougb REQUIRE(eventp != NULL && *eventp != NULL); 159224090Sdougb 160224090Sdougb (*taskp)->methods->sendanddetach(taskp, eventp); 161224090Sdougb 162224090Sdougb ENSURE(*taskp == NULL && *eventp == NULL); 163224090Sdougb} 164224090Sdougb 165224090Sdougbunsigned int 166224090Sdougbisc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type, 167224090Sdougb void *tag, isc_eventlist_t *events) 168224090Sdougb{ 169224090Sdougb REQUIRE(ISCAPI_TASK_VALID(task)); 170224090Sdougb 171224090Sdougb return (task->methods->unsend(task, sender, type, tag, events)); 172224090Sdougb} 173224090Sdougb 174224090Sdougbisc_result_t 175224090Sdougbisc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, const void *arg) 176224090Sdougb{ 177224090Sdougb REQUIRE(ISCAPI_TASK_VALID(task)); 178224090Sdougb 179224090Sdougb return (task->methods->onshutdown(task, action, arg)); 180224090Sdougb} 181224090Sdougb 182224090Sdougbvoid 183224090Sdougbisc_task_shutdown(isc_task_t *task) { 184224090Sdougb REQUIRE(ISCAPI_TASK_VALID(task)); 185224090Sdougb 186224090Sdougb task->methods->shutdown(task); 187224090Sdougb} 188224090Sdougb 189224090Sdougbvoid 190224090Sdougbisc_task_setname(isc_task_t *task, const char *name, void *tag) { 191224090Sdougb REQUIRE(ISCAPI_TASK_VALID(task)); 192224090Sdougb 193224090Sdougb task->methods->setname(task, name, tag); 194224090Sdougb} 195224090Sdougb 196224090Sdougbunsigned int 197224090Sdougbisc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag) 198224090Sdougb{ 199224090Sdougb REQUIRE(ISCAPI_TASK_VALID(task)); 200224090Sdougb 201224090Sdougb return (task->methods->purgeevents(task, sender, type, tag)); 202224090Sdougb} 203224090Sdougb 204245163Serwinvoid 205245163Serwinisc_taskmgr_setexcltask(isc_taskmgr_t *mgr, isc_task_t *task) { 206245163Serwin REQUIRE(ISCAPI_TASK_VALID(task)); 207245163Serwin return (mgr->methods->setexcltask(mgr, task)); 208245163Serwin} 209245163Serwin 210224090Sdougbisc_result_t 211245163Serwinisc_taskmgr_excltask(isc_taskmgr_t *mgr, isc_task_t **taskp) { 212245163Serwin return (mgr->methods->excltask(mgr, taskp)); 213245163Serwin} 214245163Serwin 215245163Serwinisc_result_t 216224090Sdougbisc_task_beginexclusive(isc_task_t *task) { 217224090Sdougb REQUIRE(ISCAPI_TASK_VALID(task)); 218224090Sdougb 219224090Sdougb return (task->methods->beginexclusive(task)); 220224090Sdougb} 221224090Sdougb 222224090Sdougbvoid 223224090Sdougbisc_task_endexclusive(isc_task_t *task) { 224224090Sdougb REQUIRE(ISCAPI_TASK_VALID(task)); 225224090Sdougb 226224090Sdougb task->methods->endexclusive(task); 227224090Sdougb} 228224090Sdougb 229254897Serwinvoid 230254897Serwinisc_task_setprivilege(isc_task_t *task, isc_boolean_t priv) { 231254897Serwin REQUIRE(ISCAPI_TASK_VALID(task)); 232224090Sdougb 233254897Serwin task->methods->setprivilege(task, priv); 234254897Serwin} 235254897Serwin 236254897Serwinisc_boolean_t 237254897Serwinisc_task_privilege(isc_task_t *task) { 238254897Serwin REQUIRE(ISCAPI_TASK_VALID(task)); 239254897Serwin 240254897Serwin return (task->methods->privilege(task)); 241254897Serwin} 242254897Serwin 243254897Serwin 244224090Sdougb/*% 245224090Sdougb * This is necessary for libisc's internal timer implementation. Other 246224090Sdougb * implementation might skip implementing this. 247224090Sdougb */ 248224090Sdougbunsigned int 249224090Sdougbisc_task_purgerange(isc_task_t *task, void *sender, isc_eventtype_t first, 250224090Sdougb isc_eventtype_t last, void *tag) 251224090Sdougb{ 252224090Sdougb REQUIRE(ISCAPI_TASK_VALID(task)); 253224090Sdougb 254224090Sdougb return (task->methods->purgerange(task, sender, first, last, tag)); 255224090Sdougb} 256