Skip to content
Snippets Groups Projects
Commit c17843a2 authored by Jan Včelák's avatar Jan Včelák :rocket:
Browse files

suspend background workers during reload

refs #296
parent b220735e
Branches
Tags
No related merge requests found
......@@ -588,12 +588,13 @@ int server_update_zones(const struct conf_t *conf, void *data)
{
server_t *server = (server_t *)data;
/* Prevent new events on zones waiting to be replaced. */
/* Prevent emitting of new zone events. */
if (server->zone_db) {
knot_zonedb_foreach(server->zone_db, zone_events_freeze);
}
/* Finish operations already in the queue. */
/* Suspend workers, clear wating events, finish running events. */
worker_pool_suspend(server->workers);
worker_pool_clear(server->workers);
worker_pool_wait(server->workers);
......@@ -603,7 +604,8 @@ int server_update_zones(const struct conf_t *conf, void *data)
/* Trim extra heap. */
mem_trim();
/* Plan events on new zones. */
/* Resume workers and allow events on new zones. */
worker_pool_resume(server->workers);
if (server->zone_db) {
knot_zonedb_foreach(server->zone_db, zone_events_start);
}
......
......@@ -35,6 +35,7 @@ struct worker_pool {
pthread_cond_t wake;
bool terminating; /*!< Is the pool terminating? .*/
bool suspended; /*!< Is execution temporarily suspended? .*/
int running; /*!< Number of running threads. */
worker_queue_t tasks;
};
......@@ -61,7 +62,11 @@ static int worker_main(dthread_t *thread)
break;
}
task_t *task = worker_queue_dequeue(&pool->tasks);
task_t *task = NULL;
if (!pool->suspended) {
task = worker_queue_dequeue(&pool->tasks);
}
if (task == NULL) {
pthread_cond_wait(&pool->wake, &pool->lock);
continue;
......@@ -162,6 +167,29 @@ void worker_pool_stop(worker_pool_t *pool)
dt_stop(pool->threads);
}
void worker_pool_suspend(worker_pool_t *pool)
{
if (!pool) {
return;
}
pthread_mutex_lock(&pool->lock);
pool->suspended = true;
pthread_mutex_unlock(&pool->lock);
}
void worker_pool_resume(worker_pool_t *pool)
{
if (!pool) {
return;
}
pthread_mutex_lock(&pool->lock);
pool->suspended = false;
pthread_cond_broadcast(&pool->wake);
pthread_mutex_unlock(&pool->lock);
}
void worker_pool_join(worker_pool_t *pool)
{
if (!pool) {
......
......@@ -45,6 +45,16 @@ void worker_pool_start(worker_pool_t *pool);
*/
void worker_pool_stop(worker_pool_t *pool);
/*!
* \brief Temporarily suspend the execution of worker pool.
*/
void worker_pool_suspend(worker_pool_t *pool);
/*!
* \brief Resume the execution of worker pool.
*/
void worker_pool_resume(worker_pool_t *pool);
/*!
* \brief Wait for all threads to terminate.
*/
......
......@@ -921,7 +921,7 @@ void zone_events_enqueue(zone_t *zone, zone_event_type_t type)
pthread_mutex_lock(&events->mx);
/* Possible only if no event is running at the moment. */
/* Bypass scheduler if no event is running. */
if (!events->running && !events->frozen) {
events->running = true;
event_set_time(events, type, ZONE_EVENT_IMMEDIATE);
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment