<commit_before>#include <signal.h>
#include <unistd.h>

#include <common/buffer.h>

#include <event/action.h>
#include <event/callback.h>
#include <event/event_system.h>

static void signal_reload(int);
static void signal_stop(int);

EventSystem::EventSystem(void)
: log_("/event/system"),
  queue_(),
  reload_(),
  stop_(),
  interest_queue_(),
  timeout_queue_(),
  poll_()
{
	INFO(log_) << "Starting event system.";

	signal(SIGHUP, signal_reload);
	signal(SIGINT, signal_stop);
}

EventSystem::~EventSystem()
{
}

Action *
EventSystem::poll(const EventPoll::Type& type, int fd, EventCallback *cb)
{
	Action *a = poll_.poll(type, fd, cb);
	return (a);
}

Action *
EventSystem::register_interest(const EventInterest& interest, Callback *cb)
{
	Action *a = interest_queue_[interest].append(cb);
	return (a);
}

Action *
EventSystem::schedule(Callback *cb)
{
	Action *a = queue_.append(cb);
	return (a);
}

Action *
EventSystem::timeout(unsigned secs, Callback *cb)
{
	Action *a = timeout_queue_.append(secs, cb);
	return (a);
}

void
EventSystem::start(void)
{
	for (;;) {
		/*
		 * If we have been told to stop, fire all shutdown events.
		 */
		if (stop_ && !interest_queue_[EventInterestStop].empty()) {
			INFO(log_) << "Running stop handlers.";
			if (interest_queue_[EventInterestStop].drain())
				ERROR(log_) << "Stop handlers added other stop handlers.";
			INFO(log_) << "Stop handlers have been run.";
		}

		/*
		 * If we have been told to reload, fire all shutdown events.
		 */
		if (reload_ && !interest_queue_[EventInterestReload].empty()) {
			INFO(log_) << "Running reload handlers.";
			interest_queue_[EventInterestReload].drain();
			INFO(log_) << "Reload handlers have been run.";

			reload_ = false;
			signal(SIGHUP, signal_reload);
		}

		/*
		 * If there are time-triggered events whose time has come,
		 * run them.
		 */
		if (!timeout_queue_.empty()) {
			while (timeout_queue_.ready())
				timeout_queue_.perform();
		}

		/*
		 * And then run a pending callback.
		 */
		while (!queue_.empty() && !timeout_queue_.ready()) {
			queue_.perform();
			if (stop_ || reload_)
				break;
		}

		/*
		 * Do a quick poll if necessary.
		 */
		if (!queue_.empty() || timeout_queue_.ready()) {
			if (!poll_.idle())
				poll_.poll();
			continue;
		}

		/*
		 * But if there are no pending callbacks, and no timers or
		 * file descriptors being polled, stop.
		 */
		if (timeout_queue_.empty() && poll_.idle())
			break;
		/*
		 * If there are timers ticking down, then let the poll module
		 * block until a timer will be ready.
		 * XXX Maybe block 1 second less, just in case?  We'll never
		 * be a realtime system though, so any attempt at pretending
		 * to be one, beyond giving time events priority at the top of
		 * this loop, is probably a mistake.
		 */
		if (!timeout_queue_.empty()) {<commit_msg>Simplify code and do poll regularly even in the infinite callbacks case.<commit_after>#include <signal.h>
#include <unistd.h>

#include <common/buffer.h>

#include <event/action.h>
#include <event/callback.h>
#include <event/event_system.h>

static void signal_reload(int);
static void signal_stop(int);

EventSystem::EventSystem(void)
: log_("/event/system"),
  queue_(),
  reload_(),
  stop_(),
  interest_queue_(),
  timeout_queue_(),
  poll_()
{
	INFO(log_) << "Starting event system.";

	signal(SIGHUP, signal_reload);
	signal(SIGINT, signal_stop);
}

EventSystem::~EventSystem()
{
}

Action *
EventSystem::poll(const EventPoll::Type& type, int fd, EventCallback *cb)
{
	Action *a = poll_.poll(type, fd, cb);
	return (a);
}

Action *
EventSystem::register_interest(const EventInterest& interest, Callback *cb)
{
	Action *a = interest_queue_[interest].append(cb);
	return (a);
}

Action *
EventSystem::schedule(Callback *cb)
{
	Action *a = queue_.append(cb);
	return (a);
}

Action *
EventSystem::timeout(unsigned secs, Callback *cb)
{
	Action *a = timeout_queue_.append(secs, cb);
	return (a);
}

void
EventSystem::start(void)
{
	for (;;) {
		/*
		 * If we have been told to stop, fire all shutdown events.
		 */
		if (stop_ && !interest_queue_[EventInterestStop].empty()) {
			INFO(log_) << "Running stop handlers.";
			if (interest_queue_[EventInterestStop].drain())
				ERROR(log_) << "Stop handlers added other stop handlers.";
			INFO(log_) << "Stop handlers have been run.";
		}

		/*
		 * If we have been told to reload, fire all shutdown events.
		 */
		if (reload_ && !interest_queue_[EventInterestReload].empty()) {
			INFO(log_) << "Running reload handlers.";
			interest_queue_[EventInterestReload].drain();
			INFO(log_) << "Reload handlers have been run.";

			reload_ = false;
			signal(SIGHUP, signal_reload);
		}

		/*
		 * If there are time-triggered events whose time has come,
		 * run them.
		 */
		if (!timeout_queue_.empty()) {
			while (timeout_queue_.ready())
				timeout_queue_.perform();
		}

		/*
		 * And then run a pending callback.
		 */
		while (!queue_.empty() && !timeout_queue_.ready()) {
			queue_.perform();
			if (stop_ || reload_)
				break;
			if (!poll_.idle())
				poll_.poll();
		}

		/*
		 * Do a quick poll if necessary.
		 */
		if (!queue_.empty() || timeout_queue_.ready())
			continue;

		/*
		 * But if there are no pending callbacks, and no timers or
		 * file descriptors being polled, stop.
		 */
		if (timeout_queue_.empty() && poll_.idle())
			break;
		/*
		 * If there are timers ticking down, then let the poll module
		 * block until a timer will be ready.
		 * XXX Maybe block 1 second less, just in case?  We'll never
		 * be a realtime system though, so any attempt at pretending
		 * to be one, beyond giving time events priority at the top of
		 * this loop, is probably a mistake.
		 */
		if (!timeout_queue_.empty()) {
{'fraction_non_alphanumeric': 0.14315679077084426, 'fraction_numerical': 0.0003495892326516343, 'mean_word_length': 3.694011484823626, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6304862', 'n_tokens_mistral': 2082, 'n_tokens_neox': 1826, 'n_words': 545}