X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/8c6fa3fbaccc22127280bf77a48fab5a3ee0716e..46b0747592074017ff0ea4b33d4a7194235886e5:/stargazer/eventloop.cpp diff --git a/stargazer/eventloop.cpp b/stargazer/eventloop.cpp new file mode 100644 index 00000000..36a77e9e --- /dev/null +++ b/stargazer/eventloop.cpp @@ -0,0 +1,119 @@ +#include +#include +#include + +#include "stg/locker.h" +#include "stg/common.h" +#include "eventloop.h" + +EVENT_LOOP::EVENT_LOOP() + : ACTIONS_LIST(), + _running(false), + _stopped(true), + _tid(), + _mutex(), + _condition() +{ +pthread_mutex_init(&_mutex, NULL); +pthread_cond_init(&_condition, NULL); +} + +EVENT_LOOP::~EVENT_LOOP() +{ +pthread_cond_destroy(&_condition); +pthread_mutex_destroy(&_mutex); +} + +bool EVENT_LOOP::Start() +{ +_running = true; +if (pthread_create(&_tid, NULL, Run, this)) + { + printfd(__FILE__, "EVENT_LOOP::Start - Failed to create thread: '%s'\n", strerror(errno)); + return true; + } +return false; +} + +bool EVENT_LOOP::Stop() +{ +_running = false; +// Wake up thread +pthread_cond_signal(&_condition); +// Wait until thread exit +pthread_join(_tid, NULL); +return false; +} + +void * EVENT_LOOP::Run(void * self) +{ +EVENT_LOOP * ev = static_cast(self); +ev->Runner(); +return NULL; +} + +void EVENT_LOOP::Runner() +{ +sigset_t signalSet; +sigfillset(&signalSet); +pthread_sigmask(SIG_BLOCK, &signalSet, NULL); + +_stopped = false; +printfd(__FILE__, "EVENT_LOOP::Runner - Before start\n"); +while (_running) + { + { + STG_LOCKER lock(&_mutex); + // Check for any actions... + if (empty()) + { + // ... and sleep until new actions added + printfd(__FILE__, "EVENT_LOOP::Runner - Sleeping until new actions arrived\n"); + pthread_cond_wait(&_condition, &_mutex); + } + // Check for running after wake up + if (!_running) + { + // Don't process any actions if stopping + break; + } + } + // Create new empty actions list + ACTIONS_LIST local; + // Fast swap with current + swap(local); + // Invoke all current actions + printfd(__FILE__, "EVENT_LOOP::Runner - Invoke %d actions\n", local.size()); + local.InvokeAll(); + } +printfd(__FILE__, "EVENT_LOOP::Runner - Before stop\n"); +_stopped = true; +} + +namespace { + +pthread_mutex_t singletonMutex; + +} + +EVENT_LOOP & EVENT_LOOP_SINGLETON::GetInstance() +{ +// Double-checking technique +if (!_instance) + { + STG_LOCKER lock(&singletonMutex); + if (!_instance) + { + CreateInstance(); + } + } +return *_instance; +} + +void EVENT_LOOP_SINGLETON::CreateInstance() +{ +static EVENT_LOOP loop; +_instance = &loop; +} + +EVENT_LOOP * EVENT_LOOP_SINGLETON::_instance = NULL;