<commit_before>#include "event.h"
#include <unistd.h>
#include <stdlib.h>

#define internal static

internal ax_event_loop EventLoop = {};

/* NOTE(koekeishiya): Must be thread-safe! Called through AXLibConstructEvent macro */
void AXLibAddEvent(ax_event Event)
{
    if(EventLoop.Running && Event.Handle)
    {
        pthread_mutex_lock(&EventLoop.WorkerLock);
        EventLoop.Queue.push(Event);

        pthread_cond_signal(&EventLoop.State);
        pthread_mutex_unlock(&EventLoop.WorkerLock);
    }
}

/* NOTE(koekeishiya): This function is currently unused and should probably be removed (?)
                      The callback is responsible for cleaning up the context provided for an event. */
internal void
AXLibDestroyEvent(ax_event *Event)
{
    if(Event->Context)
        free(Event->Context);

    Event->Handle = NULL;
    Event->Context = NULL;
}

/* NOTE(koekeishiya): Uses dynamic dispatch to process events of any type. */
internal void *
AXLibProcessEventQueue(void *)
{
    while(EventLoop.Running)
    {
        pthread_mutex_lock(&EventLoop.StateLock);
        while(!EventLoop.Queue.empty())
        {
            pthread_mutex_lock(&EventLoop.WorkerLock);
            ax_event Event = EventLoop.Queue.front();
            EventLoop.Queue.pop();
            pthread_mutex_unlock(&EventLoop.WorkerLock);

            (*Event.Handle)(&Event);
        }

        while(EventLoop.Queue.empty())
            pthread_cond_wait(&EventLoop.State, &EventLoop.StateLock);

        pthread_mutex_unlock(&EventLoop.StateLock);
    }

    return NULL;
}

void AXLibStartEventLoop()
{
    if((!EventLoop.Running) &&
       (pthread_mutex_init(&EventLoop.WorkerLock, NULL) == 0) &&
       (pthread_mutex_init(&EventLoop.StateLock, NULL) == 0) &&
       (pthread_cond_init(&EventLoop.State, NULL) == 0))
    {
        EventLoop.Running = true;
        pthread_create(&EventLoop.Worker, NULL, &AXLibProcessEventQueue, NULL);
    }
}

void AXLibStopEventLoop()
{
    if(EventLoop.Running)
    {<commit_msg>properly stop the event loop<commit_after>#include "event.h"
#include <unistd.h>
#include <stdlib.h>

#define internal static

internal ax_event_loop EventLoop = {};

/* NOTE(koekeishiya): Must be thread-safe! Called through AXLibConstructEvent macro */
void AXLibAddEvent(ax_event Event)
{
    if(EventLoop.Running && Event.Handle)
    {
        pthread_mutex_lock(&EventLoop.WorkerLock);
        EventLoop.Queue.push(Event);

        pthread_cond_signal(&EventLoop.State);
        pthread_mutex_unlock(&EventLoop.WorkerLock);
    }
}

/* NOTE(koekeishiya): This function is currently unused and should probably be removed (?)
                      The callback is responsible for cleaning up the context provided for an event. */
internal void
AXLibDestroyEvent(ax_event *Event)
{
    if(Event->Context)
        free(Event->Context);

    Event->Handle = NULL;
    Event->Context = NULL;
}

/* NOTE(koekeishiya): Uses dynamic dispatch to process events of any type. */
internal void *
AXLibProcessEventQueue(void *)
{
    while(EventLoop.Running)
    {
        pthread_mutex_lock(&EventLoop.StateLock);
        while(!EventLoop.Queue.empty())
        {
            pthread_mutex_lock(&EventLoop.WorkerLock);
            ax_event Event = EventLoop.Queue.front();
            EventLoop.Queue.pop();
            pthread_mutex_unlock(&EventLoop.WorkerLock);

            (*Event.Handle)(&Event);
        }

        while(EventLoop.Queue.empty() && EventLoop.Running)
            pthread_cond_wait(&EventLoop.State, &EventLoop.StateLock);

        pthread_mutex_unlock(&EventLoop.StateLock);
    }

    return NULL;
}

void AXLibStartEventLoop()
{
    if((!EventLoop.Running) &&
       (pthread_mutex_init(&EventLoop.WorkerLock, NULL) == 0) &&
       (pthread_mutex_init(&EventLoop.StateLock, NULL) == 0) &&
       (pthread_cond_init(&EventLoop.State, NULL) == 0))
    {
        EventLoop.Running = true;
        pthread_create(&EventLoop.Worker, NULL, &AXLibProcessEventQueue, NULL);
    }
}

void AXLibStopEventLoop()
{
    if(EventLoop.Running)
    {
{'fraction_non_alphanumeric': 0.11884842519685039, 'fraction_numerical': 0.0014763779527559055, 'mean_word_length': 3.1143724696356276, 'pattern_counts': {'":': 0, '<': 7, '<?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': '3470618', 'n_tokens_mistral': 1261, 'n_tokens_neox': 1227, 'n_words': 231}