Commit dbfd1b9a authored by Daniel Salzman's avatar Daniel Salzman

Revert "Merge branch 'events-race-condition' into 'master'"

This reverts merge request !532
parent 0677e972
......@@ -162,6 +162,7 @@ event_t *evsched_event_create(evsched_t *sched, event_cb_t cb, void *data)
/* Initialize. */
memset(e, 0, sizeof(event_t));
e->sched = sched;
e->cb = cb;
e->data = data;
e->hpos.pos=0;
......@@ -178,18 +179,19 @@ void evsched_event_free(event_t *ev)
free(ev);
}
int evsched_schedule(evsched_t *sched, event_t *ev, uint32_t dt)
int evsched_schedule(event_t *ev, uint32_t dt)
{
if (ev == NULL || sched == NULL) {
if (ev == NULL || ev->sched == NULL) {
return KNOT_EINVAL;
}
struct timeval new_time = timeval_in(dt);
evsched_t *sched = ev->sched;
/* Lock calendar. */
pthread_mutex_lock(&sched->heap_lock);
ev->sched = sched;
ev->tv = new_time;
/* Make sure it's not already enqueued. */
......@@ -213,7 +215,6 @@ int evsched_cancel(event_t *ev)
return KNOT_EINVAL;
}
int ret = KNOT_EOK;
evsched_t *sched = ev->sched;
/* Lock calendar. */
......@@ -222,9 +223,6 @@ int evsched_cancel(event_t *ev)
int found = heap_find(&sched->heap, (heap_val_t *)ev);
if (found > 0) {
heap_delete(&sched->heap, found);
ev->sched = NULL;
} else {
ret = KNOT_ENOENT;
}
/* Unlock calendar. */
......@@ -234,7 +232,7 @@ int evsched_cancel(event_t *ev)
/* Reset event timer. */
memset(&ev->tv, 0, sizeof(struct timeval));
return ret;
return KNOT_EOK;
}
void evsched_start(evsched_t *sched)
......
......@@ -127,7 +127,7 @@ void evsched_event_free(event_t *ev);
* \retval KNOT_EOK on success.
* \retval KNOT_EINVAL
*/
int evsched_schedule(evsched_t *sched, event_t *ev, uint32_t dt);
int evsched_schedule(event_t *ev, uint32_t dt);
/*!
* \brief Cancel a scheduled event.
......
......@@ -146,7 +146,7 @@ static void reschedule(zone_events_t *events)
time_t diff = time_until(event_get_time(events, type));
evsched_schedule(events->sched, events->event, diff * 1000);
evsched_schedule(events->event, diff * 1000);
}
/*!
......@@ -210,33 +210,13 @@ static void event_dispatch(event_t *event)
zone_events_t *events = event->data;
pthread_mutex_lock(&events->mx);
event->sched = NULL;
if (!events->running && !events->frozen) {
events->running = true;
worker_pool_assign(events->pool, &events->task);
}
pthread_cond_broadcast(&events->cancel);
pthread_mutex_unlock(&events->mx);
}
/*!
* \brief Wait until we can safely free the event. Required to avoid races.
*
* \warning Mutex events->mx is assumed to be locked.
*/
static void wait_for_cancellation(zone_events_t *events)
{
events->frozen = true;
/* Cancel current event. */
if (evsched_cancel(events->event) == KNOT_ENOENT) {
/* The event was not cancelled, wait until we stopped */
while (events->event->sched != NULL) {
pthread_cond_wait(&events->cancel, &events->mx);
}
}
}
int zone_events_init(zone_t *zone)
{
if (!zone) {
......@@ -266,7 +246,6 @@ int zone_events_setup(struct zone *zone, worker_pool_t *workers,
return KNOT_ENOMEM;
}
zone->events.sched = scheduler;
zone->events.event = event;
zone->events.pool = workers;
zone->events.timers_db = timers_db;
......@@ -280,13 +259,10 @@ void zone_events_deinit(zone_t *zone)
return;
}
zone_events_t *events = &zone->events;
pthread_mutex_lock(&events->mx);
wait_for_cancellation(events);
evsched_event_free(events->event);
pthread_mutex_unlock(&events->mx);
evsched_cancel(zone->events.event);
evsched_event_free(zone->events.event);
pthread_mutex_destroy(&events->mx);
pthread_mutex_destroy(&zone->events.mx);
memset(&zone->events, 0, sizeof(zone->events));
}
......@@ -359,8 +335,11 @@ void zone_events_freeze(zone_t *zone)
/* Prevent new events being enqueued. */
pthread_mutex_lock(&events->mx);
wait_for_cancellation(events);
events->frozen = true;
pthread_mutex_unlock(&events->mx);
/* Cancel current event. */
evsched_cancel(events->event);
}
void zone_events_start(zone_t *zone)
......
......@@ -47,11 +47,9 @@ typedef enum zone_event_type {
typedef struct zone_events {
pthread_mutex_t mx; //!< Mutex protecting the struct.
pthread_cond_t cancel;
bool running; //!< Some zone event is being run.
bool frozen; //!< Terminated, don't schedule new events.
evsched_t *sched;
event_t *event; //!< Scheduler event.
worker_pool_t *pool; //!< Server worker pool.
knot_db_t *timers_db; //!< Persistent zone timers database.
......@@ -88,8 +86,6 @@ int zone_events_setup(struct zone *zone, worker_pool_t *workers,
/*!
* \brief Deinitialize zone events.
*
* \warning It is expected that the worker threads are suspended and cleared.
*
* \param zone Zone whose events we want to deinitialize.
*/
void zone_events_deinit(struct zone *zone);
......
Markdown is supported
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