<commit_before>#include <klingklang/event.h>

#include <fcntl.h>
#include <signal.h>
#include <errno.h>

#ifdef HAVE_UNISTD_H
#  include <unistd.h>
#endif

int
kk_event_queue_init (kk_event_queue_t **queue)
{
  kk_event_queue_t *result;

  result = calloc (1, sizeof (kk_event_queue_t));
  if (result == NULL)
    goto error;

  if (pipe (result->fd) == -1)
    goto error;

  if (fcntl (result->fd[0], F_SETFL, O_NONBLOCK) == -1)
    goto error;

  if (fcntl (result->fd[1], F_SETFL, O_NONBLOCK) == -1)
    goto error;

  *queue = result;
  return 0;
error:
  kk_event_queue_free (result);
  *queue = NULL;
  return -1;
}

int
kk_event_queue_free (kk_event_queue_t *queue)
{
  if (queue == NULL)
    return 0;

  if (queue->fd[0])
    close (queue->fd[0]);
  if (queue->fd[1])
    close (queue->fd[1]);
  free (queue);
  return 0;
}

int
kk_event_queue_write (kk_event_queue_t *queue, void *ptr, size_t n)
{
  kk_event_t event;

  if (n > sizeof (kk_event_t))
    return -1;

  memset (&event, 0, sizeof (kk_event_t));
  memcpy (&event, ptr, n);
  if (write (queue->fd[1], &event, sizeof (kk_event_t)) <= 0)
    return -1;
  return 0;
}

int
kk_event_queue_get_read_fd (kk_event_queue_t *queue)
{
  return queue->fd[0];
}

int
kk_event_queue_get_write_fd (kk_event_queue_t *queue)
{
  return queue->fd[1];
}

int
kk_event_loop_init (kk_event_loop_t **loop, size_t cap)
{
  kk_event_loop_t *result;

  result = calloc (1, sizeof (kk_event_loop_t) + cap *sizeof (kk_event_handler_t));
  if (result == NULL)
    goto error;

  result->cap = cap;
  result->len = 0;
  *loop = result;
  return 0;
error:
  kk_event_loop_free (result);
  *loop = NULL;
  return -1;
}

int
kk_event_loop_free (kk_event_loop_t *loop)
{
  free (loop);
  return 0;
}

int
kk_event_loop_exit (kk_event_loop_t *loop)
{
  if (loop->running)
    loop->exit = 1;
  return 0;
}

int<commit_msg>exit event loop and terminate process gracefully on receiving signals SIGINT and SIGTERM<commit_after>#include <klingklang/base.h>
#include <klingklang/event.h>
#include <klingklang/util.h>

#include <fcntl.h>
#include <signal.h>
#include <errno.h>

#ifdef HAVE_UNISTD_H
#  include <unistd.h>
#endif

int
kk_event_queue_init (kk_event_queue_t **queue)
{
  kk_event_queue_t *result;

  result = calloc (1, sizeof (kk_event_queue_t));
  if (result == NULL)
    goto error;

  if (pipe (result->fd) == -1)
    goto error;

  if (fcntl (result->fd[0], F_SETFL, O_NONBLOCK) == -1)
    goto error;

  if (fcntl (result->fd[1], F_SETFL, O_NONBLOCK) == -1)
    goto error;

  *queue = result;
  return 0;
error:
  kk_event_queue_free (result);
  *queue = NULL;
  return -1;
}

int
kk_event_queue_free (kk_event_queue_t *queue)
{
  if (queue == NULL)
    return 0;

  if (queue->fd[0])
    close (queue->fd[0]);
  if (queue->fd[1])
    close (queue->fd[1]);
  free (queue);
  return 0;
}

int
kk_event_queue_write (kk_event_queue_t *queue, void *ptr, size_t n)
{
  kk_event_t event;

  if (n > sizeof (kk_event_t))
    return -1;

  memset (&event, 0, sizeof (kk_event_t));
  memcpy (&event, ptr, n);
  if (write (queue->fd[1], &event, sizeof (kk_event_t)) <= 0)
    return -1;
  return 0;
}

int
kk_event_queue_get_read_fd (kk_event_queue_t *queue)
{
  return queue->fd[0];
}

int
kk_event_queue_get_write_fd (kk_event_queue_t *queue)
{
  return queue->fd[1];
}

static kk_event_loop_t *main_loop = NULL;

static void
_kk_event_loop_signal (int signo)
{
  /**
   * If there's no event loop active, terminate process by calling exit().
   * Otherwise exit the event loop and let the process terminate gracefully.
   */
  if (main_loop == NULL) {
    kk_log (KK_LOG_DEBUG, "Caught signal %d. Exiting process.");
    exit (EXIT_SUCCESS);
  }
  else {
    kk_log (KK_LOG_DEBUG, "Caught signal %d. Exiting main loop.", signo);
    kk_event_loop_exit (main_loop);
  }
}

static void
_kk_event_loop_init_sigaction (void)
{
  struct sigaction act;

  sigemptyset (&act.sa_mask);
  act.sa_sigaction = NULL;
  act.sa_handler = _kk_event_loop_signal;
  act.sa_flags = 0;

  sigaction (SIGTERM, &act, NULL);
  sigaction (SIGINT, &act, NULL);
}

int
kk_event_loop_init (kk_event_loop_t ** loop, size_t cap)
{
  kk_event_loop_t *result;

  if (main_loop)
    return -1;

  /**
   * Register signal handler which helps us gracefully exiting this loop on
   * receiving the signals SIGTERM or SIGINT.
   */
  _kk_event_loop_init_sigaction ();

  result = calloc (1, sizeof (kk_event_loop_t) + cap * sizeof (kk_event_handler_t));
  if (result == NULL)
    goto error;
  result->cap = cap;
  result->len = 0;
  *loop = main_loop = result;
  return 0;
error:
  kk_event_loop_free (result);
  *loop = main_loop = NULL;
  return -1;
}

int
kk_event_loop_free (kk_event_loop_t *loop)
{
  main_loop = NULL;
  free (loop);
  return 0;
}

int
kk_event_loop_exit (kk_event_loop_t *loop)
{
  if (loop->running)
    loop->exit = 1;
  return 0;
}

int
{'fraction_non_alphanumeric': 0.13556193601312552, 'fraction_numerical': 0.012305168170631665, 'mean_word_length': 3.7720156555772992, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 45, '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': '5139287', 'n_tokens_mistral': 2052, 'n_tokens_neox': 1987, 'n_words': 491}