if (!fr_atomic_queue_pop(aq, (void **) &m)) return 0;
- fr_assert(m->status == FR_CONTROL_MESSAGE_USED);
+ fr_assert_msg(m->status == FR_CONTROL_MESSAGE_USED, "Bad control message state, expected %u got %u",
+ FR_CONTROL_MESSAGE_USED, m->status);
/*
* There isn't enough room to store the data, die.
pthread_t thread_id; //!< for self
- bool started; //!< Set to true when the first worker is added.
bool suspended; //!< whether or not we're suspended.
fr_log_t const *log; //!< log destination
int signal_pipe[2]; //!< Pipe for signalling the worker in an orderly way.
///< This is more deterministic than using async signals.
+ bool exiting; //!< are we exiting?
+
fr_network_config_t config; //!< configuration
fr_network_worker_t *workers[MAX_WORKERS]; //!< each worker
};
fr_channel_set_recv_reply(w->channel, nr, fr_network_recv_reply);
nr->num_workers++;
- nr->started = true;
/*
* Insert the worker into the array of workers.
(void) fr_event_pre_delete(nr->el, fr_network_pre_event, nr);
(void) fr_event_post_delete(nr->el, fr_network_post_event, nr);
+ nr->exiting = true;
fr_event_fd_delete(nr->el, nr->signal_pipe[0], FR_EVENT_FILTER_IO);
return 0;
*/
void fr_network(fr_network_t *nr)
{
- while (likely(((nr->num_workers > 0) || !nr->started))) {
+ while (likely((nr->num_workers > 0) || !nr->exiting)) {
bool wait_for_event;
int num_events;
fr_event_service(nr->el);
}
}
+ return;
}
/** Signal a network thread to exit