Lines Matching +full:lock +full:- +full:state
2 * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1998-2003 Internet Software Consortium.
107 isc_mutex_t lock; member
108 /* Locked by task lock. */
109 task_state_t state; member
118 /* Locked by task manager lock. */
127 #define TASK_SHUTTINGDOWN(t) (((t)->flags & TASK_F_SHUTTINGDOWN) \
139 isc_mutex_t lock; member
144 /* Locked by task manager lock. */
166 #define FINISHED(m) ((m)->exiting && EMPTY((m)->tasks))
298 isc__taskmgr_t *manager = task->manager; in task_finished()
300 REQUIRE(EMPTY(task->events)); in task_finished()
301 REQUIRE(EMPTY(task->on_shutdown)); in task_finished()
302 REQUIRE(task->references == 0); in task_finished()
303 REQUIRE(task->state == task_state_done); in task_finished()
307 LOCK(&manager->lock); in task_finished()
308 UNLINK(manager->tasks, task, link); in task_finished()
317 BROADCAST(&manager->work_available); in task_finished()
320 UNLOCK(&manager->lock); in task_finished()
322 DESTROYLOCK(&task->lock); in task_finished()
323 task->common.impmagic = 0; in task_finished()
324 task->common.magic = 0; in task_finished()
325 isc_mem_put(manager->mctx, task, sizeof(*task)); in task_finished()
340 task = isc_mem_get(manager->mctx, sizeof(*task)); in isc__task_create()
344 result = isc_mutex_init(&task->lock); in isc__task_create()
346 isc_mem_put(manager->mctx, task, sizeof(*task)); in isc__task_create()
349 LOCK(&manager->lock); in isc__task_create()
350 LOCK(&task->lock); /* helps coverity analysis noise ratio */ in isc__task_create()
351 task->manager = manager; in isc__task_create()
352 task->state = task_state_idle; in isc__task_create()
353 task->references = 1; in isc__task_create()
354 INIT_LIST(task->events); in isc__task_create()
355 INIT_LIST(task->on_shutdown); in isc__task_create()
356 task->quantum = quantum; in isc__task_create()
357 task->flags = 0; in isc__task_create()
358 task->now = 0; in isc__task_create()
359 memset(task->name, 0, sizeof(task->name)); in isc__task_create()
360 task->tag = NULL; in isc__task_create()
364 UNLOCK(&task->lock); in isc__task_create()
365 UNLOCK(&manager->lock); in isc__task_create()
368 LOCK(&manager->lock); in isc__task_create()
369 if (!manager->exiting) { in isc__task_create()
370 if (task->quantum == 0) in isc__task_create()
371 task->quantum = manager->default_quantum; in isc__task_create()
372 APPEND(manager->tasks, task, link); in isc__task_create()
375 UNLOCK(&manager->lock); in isc__task_create()
378 DESTROYLOCK(&task->lock); in isc__task_create()
379 isc_mem_put(manager->mctx, task, sizeof(*task)); in isc__task_create()
383 task->common.methods = (isc_taskmethods_t *)&taskmethods; in isc__task_create()
384 task->common.magic = ISCAPI_TASK_MAGIC; in isc__task_create()
385 task->common.impmagic = TASK_MAGIC; in isc__task_create()
404 LOCK(&source->lock); in isc__task_attach()
405 source->references++; in isc__task_attach()
406 UNLOCK(&source->lock); in isc__task_attach()
417 * Caller must be holding the task's lock. in task_shutdown()
425 task->flags |= TASK_F_SHUTTINGDOWN; in task_shutdown()
426 if (task->state == task_state_idle) { in task_shutdown()
427 INSIST(EMPTY(task->events)); in task_shutdown()
428 task->state = task_state_ready; in task_shutdown()
431 INSIST(task->state == task_state_ready || in task_shutdown()
432 task->state == task_state_running); in task_shutdown()
437 for (event = TAIL(task->on_shutdown); in task_shutdown()
441 DEQUEUE(task->on_shutdown, event, ev_link); in task_shutdown()
442 ENQUEUE(task->events, event, ev_link); in task_shutdown()
452 * Caller must NOT hold manager lock.
456 isc__taskmgr_t *manager = task->manager; in task_ready()
462 REQUIRE(task->state == task_state_ready); in task_ready()
466 LOCK(&manager->lock); in task_ready()
469 if (manager->mode == isc_taskmgrmode_normal || has_privilege) in task_ready()
470 SIGNAL(&manager->work_available); in task_ready()
472 UNLOCK(&manager->lock); in task_ready()
479 * Caller must be holding the task lock. in task_detach()
482 REQUIRE(task->references > 0); in task_detach()
486 task->references--; in task_detach()
487 if (task->references == 0 && task->state == task_state_idle) { in task_detach()
488 INSIST(EMPTY(task->events)); in task_detach()
493 * depending on its state, but it's easier to just in task_detach()
497 task->state = task_state_ready; in task_detach()
519 LOCK(&task->lock); in isc__task_detach()
521 UNLOCK(&task->lock); in isc__task_detach()
535 * Caller must be holding the task lock. in task_send()
541 REQUIRE(event->ev_type > 0); in task_send()
542 REQUIRE(task->state != task_state_done); in task_send()
546 if (task->state == task_state_idle) { in task_send()
548 INSIST(EMPTY(task->events)); in task_send()
549 task->state = task_state_ready; in task_send()
551 INSIST(task->state == task_state_ready || in task_send()
552 task->state == task_state_running); in task_send()
553 ENQUEUE(task->events, event, ev_link); in task_send()
575 * some processing is deferred until after the lock is released. in isc__task_send()
577 LOCK(&task->lock); in isc__task_send()
579 UNLOCK(&task->lock); in isc__task_send()
587 * this while holding the task lock, we could deadlock. in isc__task_send()
589 * We've changed the state to ready, so no one else will in isc__task_send()
591 * only way to leave the ready state is by executing the in isc__task_send()
594 * between the time we released the task lock, and the time in isc__task_send()
617 LOCK(&task->lock); in isc__task_sendanddetach()
620 UNLOCK(&task->lock); in isc__task_sendanddetach()
624 * the task lock, and thus the task cannot switch from ready back to in isc__task_sendanddetach()
635 #define PURGE_OK(event) (((event)->ev_attributes & ISC_EVENTATTR_NOPURGE) == 0)
658 LOCK(&task->lock); in dequeue_events()
660 for (event = HEAD(task->events); event != NULL; event = next_event) { in dequeue_events()
662 if (event->ev_type >= first && event->ev_type <= last && in dequeue_events()
663 (sender == NULL || event->ev_sender == sender) && in dequeue_events()
664 (tag == NULL || event->ev_tag == tag) && in dequeue_events()
666 DEQUEUE(task->events, event, ev_link); in dequeue_events()
672 UNLOCK(&task->lock); in dequeue_events()
703 * Note that purging never changes the state of the task. in isc__task_purgerange()
742 * Purging never changes the state of the task. in isc__task_purgeevent()
745 LOCK(&task->lock); in isc__task_purgeevent()
746 for (curr_event = HEAD(task->events); in isc__task_purgeevent()
751 DEQUEUE(task->events, curr_event, ev_link); in isc__task_purgeevent()
755 UNLOCK(&task->lock); in isc__task_purgeevent()
811 event = isc_event_allocate(task->manager->mctx, in isc__task_onshutdown()
820 LOCK(&task->lock); in isc__task_onshutdown()
825 ENQUEUE(task->on_shutdown, event, ev_link); in isc__task_onshutdown()
826 UNLOCK(&task->lock); in isc__task_onshutdown()
829 isc_mem_put(task->manager->mctx, event, sizeof(*event)); in isc__task_onshutdown()
845 LOCK(&task->lock); in isc__task_shutdown()
847 UNLOCK(&task->lock); in isc__task_shutdown()
876 LOCK(&task->lock); in isc__task_setname()
877 memset(task->name, 0, sizeof(task->name)); in isc__task_setname()
878 strncpy(task->name, name, sizeof(task->name) - 1); in isc__task_setname()
879 task->tag = tag; in isc__task_setname()
880 UNLOCK(&task->lock); in isc__task_setname()
889 return (task->name); in isc__task_getname()
898 return (task->tag); in isc__task_gettag()
908 LOCK(&task->lock); in isc__task_getcurrenttime()
909 *t = task->now; in isc__task_getcurrenttime()
910 UNLOCK(&task->lock); in isc__task_getcurrenttime()
922 * Caller must hold the task manager lock.
928 if (manager->mode == isc_taskmgrmode_normal) in empty_readyq()
929 queue = manager->ready_tasks; in empty_readyq()
931 queue = manager->ready_priority_tasks; in empty_readyq()
942 * Caller must hold the task manager lock.
948 if (manager->mode == isc_taskmgrmode_normal) in pop_readyq()
949 task = HEAD(manager->ready_tasks); in pop_readyq()
951 task = HEAD(manager->ready_priority_tasks); in pop_readyq()
954 DEQUEUE(manager->ready_tasks, task, ready_link); in pop_readyq()
956 DEQUEUE(manager->ready_priority_tasks, task, in pop_readyq()
967 * Caller must hold the task manager lock.
971 ENQUEUE(manager->ready_tasks, task, ready_link); in push_readyq()
972 if ((task->flags & TASK_F_PRIVILEGED) != 0) in push_readyq()
973 ENQUEUE(manager->ready_priority_tasks, task, in push_readyq()
989 * Again we're trying to hold the lock for as short a time as possible in dispatch()
992 * In both while loops, the appropriate lock must be held before the in dispatch()
993 * while body starts. Code which acquired the lock at the top of in dispatch()
999 * LOCK(); in dispatch()
1003 * LOCK(); in dispatch()
1009 * LOCK(); in dispatch()
1014 * Note how if the loop continues we unlock and then immediately lock. in dispatch()
1016 * unlocks. Also note that the lock is not held when the while in dispatch()
1022 * LOCK(); in dispatch()
1029 * LOCK(); in dispatch()
1035 * unlocks. The while expression is always protected by the lock. in dispatch()
1042 LOCK(&manager->lock); in dispatch()
1049 * the task while only holding the manager lock, and then in dispatch()
1050 * change the task to running state while only holding the in dispatch()
1051 * task lock. in dispatch()
1056 while ((empty_readyq(manager) || manager->pause_requested || in dispatch()
1057 manager->exclusive_requested) && !FINISHED(manager)) in dispatch()
1062 WAIT(&manager->work_available, &manager->lock); in dispatch()
1086 * Note we only unlock the manager lock if we actually in dispatch()
1088 * lock before exiting the 'if (task != NULL)' block. in dispatch()
1090 manager->tasks_running++; in dispatch()
1091 UNLOCK(&manager->lock); in dispatch()
1093 LOCK(&task->lock); in dispatch()
1094 INSIST(task->state == task_state_ready); in dispatch()
1095 task->state = task_state_running; in dispatch()
1098 isc_stdtime_get(&task->now); in dispatch()
1100 if (!EMPTY(task->events)) { in dispatch()
1101 event = HEAD(task->events); in dispatch()
1102 DEQUEUE(task->events, event, ev_link); in dispatch()
1111 if (event->ev_action != NULL) { in dispatch()
1112 UNLOCK(&task->lock); in dispatch()
1113 (event->ev_action)( in dispatch()
1116 LOCK(&task->lock); in dispatch()
1124 if (task->references == 0 && in dispatch()
1125 EMPTY(task->events) && in dispatch()
1141 * the "if EMPTY(task->events)" block in dispatch()
1155 if (EMPTY(task->events)) { in dispatch()
1164 if (task->references == 0 && in dispatch()
1175 task->state = task_state_done; in dispatch()
1177 task->state = task_state_idle; in dispatch()
1179 } else if (dispatch_count >= task->quantum) { in dispatch()
1194 task->state = task_state_ready; in dispatch()
1199 UNLOCK(&task->lock); in dispatch()
1204 LOCK(&manager->lock); in dispatch()
1205 manager->tasks_running--; in dispatch()
1207 if (manager->exclusive_requested && in dispatch()
1208 manager->tasks_running == 1) { in dispatch()
1209 SIGNAL(&manager->exclusive_granted); in dispatch()
1210 } else if (manager->pause_requested && in dispatch()
1211 manager->tasks_running == 0) { in dispatch()
1212 SIGNAL(&manager->paused); in dispatch()
1239 if ((task->flags & TASK_F_PRIVILEGED) != 0) in dispatch()
1253 if (manager->tasks_running == 0 && empty_readyq(manager)) { in dispatch()
1254 manager->mode = isc_taskmgrmode_normal; in dispatch()
1256 BROADCAST(&manager->work_available); in dispatch()
1262 ISC_LIST_APPENDLIST(manager->ready_tasks, new_ready_tasks, ready_link); in dispatch()
1263 ISC_LIST_APPENDLIST(manager->ready_priority_tasks, new_priority_tasks, in dispatch()
1266 manager->mode = isc_taskmgrmode_normal; in dispatch()
1269 UNLOCK(&manager->lock); in dispatch()
1300 LOCK(&manager->lock); in manager_free()
1302 (void)isc_condition_destroy(&manager->exclusive_granted); in manager_free()
1303 (void)isc_condition_destroy(&manager->work_available); in manager_free()
1304 (void)isc_condition_destroy(&manager->paused); in manager_free()
1305 isc_mem_free(manager->mctx, manager->threads); in manager_free()
1307 manager->common.impmagic = 0; in manager_free()
1308 manager->common.magic = 0; in manager_free()
1309 mctx = manager->mctx; in manager_free()
1310 UNLOCK(&manager->lock); in manager_free()
1311 DESTROYLOCK(&manager->lock); in manager_free()
1342 if (taskmgr->refs == 0) in isc__taskmgr_create()
1344 taskmgr->refs++; in isc__taskmgr_create()
1353 manager->common.methods = &taskmgrmethods; in isc__taskmgr_create()
1354 manager->common.impmagic = TASK_MANAGER_MAGIC; in isc__taskmgr_create()
1355 manager->common.magic = ISCAPI_TASKMGR_MAGIC; in isc__taskmgr_create()
1356 manager->mode = isc_taskmgrmode_normal; in isc__taskmgr_create()
1357 manager->mctx = NULL; in isc__taskmgr_create()
1358 result = isc_mutex_init(&manager->lock); in isc__taskmgr_create()
1361 LOCK(&manager->lock); in isc__taskmgr_create()
1364 manager->workers = 0; in isc__taskmgr_create()
1365 manager->threads = isc_mem_allocate(mctx, in isc__taskmgr_create()
1367 if (manager->threads == NULL) { in isc__taskmgr_create()
1371 if (isc_condition_init(&manager->work_available) != ISC_R_SUCCESS) { in isc__taskmgr_create()
1379 if (isc_condition_init(&manager->exclusive_granted) != ISC_R_SUCCESS) { in isc__taskmgr_create()
1387 if (isc_condition_init(&manager->paused) != ISC_R_SUCCESS) { in isc__taskmgr_create()
1398 manager->default_quantum = default_quantum; in isc__taskmgr_create()
1399 INIT_LIST(manager->tasks); in isc__taskmgr_create()
1400 INIT_LIST(manager->ready_tasks); in isc__taskmgr_create()
1401 INIT_LIST(manager->ready_priority_tasks); in isc__taskmgr_create()
1402 manager->tasks_running = 0; in isc__taskmgr_create()
1403 manager->exclusive_requested = ISC_FALSE; in isc__taskmgr_create()
1404 manager->pause_requested = ISC_FALSE; in isc__taskmgr_create()
1405 manager->exiting = ISC_FALSE; in isc__taskmgr_create()
1407 isc_mem_attach(mctx, &manager->mctx); in isc__taskmgr_create()
1415 &manager->threads[manager->workers]) == in isc__taskmgr_create()
1417 manager->workers++; in isc__taskmgr_create()
1421 UNLOCK(&manager->lock); in isc__taskmgr_create()
1430 manager->refs = 1; in isc__taskmgr_create()
1431 UNLOCK(&manager->lock); in isc__taskmgr_create()
1441 (void)isc_condition_destroy(&manager->exclusive_granted); in isc__taskmgr_create()
1443 (void)isc_condition_destroy(&manager->work_available); in isc__taskmgr_create()
1445 isc_mem_free(mctx, manager->threads); in isc__taskmgr_create()
1447 UNLOCK(&manager->lock); in isc__taskmgr_create()
1448 DESTROYLOCK(&manager->lock); in isc__taskmgr_create()
1474 manager->refs--; in isc__taskmgr_destroy()
1475 if (manager->refs > 0) { in isc__taskmgr_destroy()
1483 * Only one non-worker thread may ever call this routine. in isc__taskmgr_destroy()
1485 * task manager, it should ask some non-worker thread to call in isc__taskmgr_destroy()
1491 * Unlike elsewhere, we're going to hold this lock a long time. in isc__taskmgr_destroy()
1496 * task manager lock and a task lock at the same time. in isc__taskmgr_destroy()
1499 LOCK(&manager->lock); in isc__taskmgr_destroy()
1504 INSIST(!manager->exiting); in isc__taskmgr_destroy()
1505 manager->exiting = ISC_TRUE; in isc__taskmgr_destroy()
1510 manager->mode = isc_taskmgrmode_normal; in isc__taskmgr_destroy()
1516 for (task = HEAD(manager->tasks); in isc__taskmgr_destroy()
1519 LOCK(&task->lock); in isc__taskmgr_destroy()
1522 UNLOCK(&task->lock); in isc__taskmgr_destroy()
1528 * it will cause the workers to see manager->exiting. in isc__taskmgr_destroy()
1530 BROADCAST(&manager->work_available); in isc__taskmgr_destroy()
1531 UNLOCK(&manager->lock); in isc__taskmgr_destroy()
1536 for (i = 0; i < manager->workers; i++) in isc__taskmgr_destroy()
1537 (void)isc_thread_join(manager->threads[i], NULL); in isc__taskmgr_destroy()
1542 UNLOCK(&manager->lock); in isc__taskmgr_destroy()
1546 if (!ISC_LIST_EMPTY(manager->tasks)) in isc__taskmgr_destroy()
1549 INSIST(ISC_LIST_EMPTY(manager->tasks)); in isc__taskmgr_destroy()
1564 LOCK(&manager->lock); in isc__taskmgr_setmode()
1565 manager->mode = mode; in isc__taskmgr_setmode()
1566 UNLOCK(&manager->lock); in isc__taskmgr_setmode()
1573 LOCK(&manager->lock); in isc__taskmgr_mode()
1574 mode = manager->mode; in isc__taskmgr_mode()
1575 UNLOCK(&manager->lock); in isc__taskmgr_mode()
1592 LOCK(&manager->lock); in isc__taskmgr_ready()
1594 UNLOCK(&manager->lock); in isc__taskmgr_ready()
1619 LOCK(&manager->lock); in isc__taskmgr_pause()
1620 while (manager->tasks_running > 0) { in isc__taskmgr_pause()
1621 WAIT(&manager->paused, &manager->lock); in isc__taskmgr_pause()
1623 manager->pause_requested = ISC_TRUE; in isc__taskmgr_pause()
1624 UNLOCK(&manager->lock); in isc__taskmgr_pause()
1631 LOCK(&manager->lock); in isc__taskmgr_resume()
1632 if (manager->pause_requested) { in isc__taskmgr_resume()
1633 manager->pause_requested = ISC_FALSE; in isc__taskmgr_resume()
1634 BROADCAST(&manager->work_available); in isc__taskmgr_resume()
1636 UNLOCK(&manager->lock); in isc__taskmgr_resume()
1644 isc__taskmgr_t *manager = task->manager; in isc__task_beginexclusive()
1645 REQUIRE(task->state == task_state_running); in isc__task_beginexclusive()
1646 LOCK(&manager->lock); in isc__task_beginexclusive()
1647 if (manager->exclusive_requested) { in isc__task_beginexclusive()
1648 UNLOCK(&manager->lock); in isc__task_beginexclusive()
1651 manager->exclusive_requested = ISC_TRUE; in isc__task_beginexclusive()
1652 while (manager->tasks_running > 1) { in isc__task_beginexclusive()
1653 WAIT(&manager->exclusive_granted, &manager->lock); in isc__task_beginexclusive()
1655 UNLOCK(&manager->lock); in isc__task_beginexclusive()
1666 isc__taskmgr_t *manager = task->manager; in isc__task_endexclusive()
1668 REQUIRE(task->state == task_state_running); in isc__task_endexclusive()
1669 LOCK(&manager->lock); in isc__task_endexclusive()
1670 REQUIRE(manager->exclusive_requested); in isc__task_endexclusive()
1671 manager->exclusive_requested = ISC_FALSE; in isc__task_endexclusive()
1672 BROADCAST(&manager->work_available); in isc__task_endexclusive()
1673 UNLOCK(&manager->lock); in isc__task_endexclusive()
1682 isc__taskmgr_t *manager = task->manager; in isc__task_setprivilege()
1685 LOCK(&task->lock); in isc__task_setprivilege()
1686 oldpriv = ISC_TF((task->flags & TASK_F_PRIVILEGED) != 0); in isc__task_setprivilege()
1688 task->flags |= TASK_F_PRIVILEGED; in isc__task_setprivilege()
1690 task->flags &= ~TASK_F_PRIVILEGED; in isc__task_setprivilege()
1691 UNLOCK(&task->lock); in isc__task_setprivilege()
1696 LOCK(&manager->lock); in isc__task_setprivilege()
1698 ENQUEUE(manager->ready_priority_tasks, task, in isc__task_setprivilege()
1701 DEQUEUE(manager->ready_priority_tasks, task, in isc__task_setprivilege()
1703 UNLOCK(&manager->lock); in isc__task_setprivilege()
1711 LOCK(&task->lock); in isc__task_privilege()
1712 priv = ISC_TF((task->flags & TASK_F_PRIVILEGED) != 0); in isc__task_privilege()
1713 UNLOCK(&task->lock); in isc__task_privilege()
1739 LOCK(&mgr->lock); in isc_taskmgr_renderxml()
1742 * Write out the thread-model, and some details about each depending in isc_taskmgr_renderxml()
1745 xmlTextWriterStartElement(writer, ISC_XMLCHAR "thread-model"); in isc_taskmgr_renderxml()
1751 xmlTextWriterStartElement(writer, ISC_XMLCHAR "worker-threads"); in isc_taskmgr_renderxml()
1752 xmlTextWriterWriteFormatString(writer, "%d", mgr->workers); in isc_taskmgr_renderxml()
1753 xmlTextWriterEndElement(writer); /* worker-threads */ in isc_taskmgr_renderxml()
1756 xmlTextWriterWriteString(writer, ISC_XMLCHAR "non-threaded"); in isc_taskmgr_renderxml()
1760 xmlTextWriterWriteFormatString(writer, "%d", mgr->refs); in isc_taskmgr_renderxml()
1764 xmlTextWriterStartElement(writer, ISC_XMLCHAR "default-quantum"); in isc_taskmgr_renderxml()
1765 xmlTextWriterWriteFormatString(writer, "%d", mgr->default_quantum); in isc_taskmgr_renderxml()
1766 xmlTextWriterEndElement(writer); /* default-quantum */ in isc_taskmgr_renderxml()
1768 xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-running"); in isc_taskmgr_renderxml()
1769 xmlTextWriterWriteFormatString(writer, "%d", mgr->tasks_running); in isc_taskmgr_renderxml()
1770 xmlTextWriterEndElement(writer); /* tasks-running */ in isc_taskmgr_renderxml()
1772 xmlTextWriterEndElement(writer); /* thread-model */ in isc_taskmgr_renderxml()
1775 task = ISC_LIST_HEAD(mgr->tasks); in isc_taskmgr_renderxml()
1777 LOCK(&task->lock); in isc_taskmgr_renderxml()
1780 if (task->name[0] != 0) { in isc_taskmgr_renderxml()
1783 task->name); in isc_taskmgr_renderxml()
1788 xmlTextWriterWriteFormatString(writer, "%d", task->references); in isc_taskmgr_renderxml()
1795 xmlTextWriterStartElement(writer, ISC_XMLCHAR "state"); in isc_taskmgr_renderxml()
1797 statenames[task->state]); in isc_taskmgr_renderxml()
1798 xmlTextWriterEndElement(writer); /* state */ in isc_taskmgr_renderxml()
1801 xmlTextWriterWriteFormatString(writer, "%d", task->quantum); in isc_taskmgr_renderxml()
1806 UNLOCK(&task->lock); in isc_taskmgr_renderxml()
1811 UNLOCK(&mgr->lock); in isc_taskmgr_renderxml()