signalTimer

simple timer using SIGALARM
git clone https://noulin.net/git/signalTimer.git
Log | Files | Refs | LICENSE

commit fd7152bda1826962040ae10913ed482a523b19af
parent 6bd38b71579c338de0a7956d61e8b241c5b8b925
Author: Remy Noulin <loader2x@gmail.com>
Date:   Sun, 20 May 2018 10:44:53 +0200

signalTimer library

package.yml           |  15 ++++
signalTimer.c         | 205 ++++++++++++++++++++++++++++++++++++++++++++++++++
signalTimer.h         |  97 ++++++++++++++++++++++++
signalTimerInternal.h |   6 ++
test.c                |  41 ++++++++++
5 files changed, 364 insertions(+)

Diffstat:
Apackage.yml | 15+++++++++++++++
AsignalTimer.c | 205+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AsignalTimer.h | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AsignalTimerInternal.h | 6++++++
Atest.c | 41+++++++++++++++++++++++++++++++++++++++++
5 files changed, 364 insertions(+), 0 deletions(-)

diff --git a/package.yml b/package.yml @@ -0,0 +1,15 @@ +--- + name: signalTimer + version: 0.0.3 + description: "simple timer using SIGALARM" + bin: ./signalTimer.c + repository: + type: git + url: git+https://github.com/RemyNoulin/signalTimer.git + keywords: + - utility + author: Remy + license: MIT + bugs: + url: https://github.com/RemyNoulin/signalTimer/issues + homepage: https://github.com/RemyNoulin/signalTimer#readme diff --git a/signalTimer.c b/signalTimer.c @@ -0,0 +1,205 @@ + + +/* Add class methods and modify the base functions (free, duplicate, ...) where there are the TODOs (TODO)*/ + +#include "libsheepyObject.h" +#include "signalTimer.h" +#include "signalTimerInternal.h" + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include <sys/time.h> // setitimer +#include <unistd.h> // for pause +#include <signal.h> // signal + +void initiateSignalTimer(signalTimert *self); +void registerMethodsSignalTimer(signalTimerFunctionst *f); +void initiateAllocateSignalTimer(signalTimert **self); +void finalizeSignalTimer(void); +signalTimert* allocSignalTimer(void); +internal void freeSignalTimer(signalTimert *self); +internal void terminateSignalTimer(signalTimert **self); +internal char* toStringSignalTimer(signalTimert *self); +internal signalTimert* duplicateSignalTimer(signalTimert *self); +internal void smashSignalTimer(signalTimert **self); +internal void finishSignalTimer(signalTimert **self); + +internal bool startSignalTimer(signalTimert *self, u64 interval, void (*callback)(void *), void *args); +internal void stopSignalTimer(signalTimert *self); +internal void pauseSignalTimer(signalTimert *self); +internal void pauseProcessSignalTimer(signalTimert *self); +internal void restartSignalTimer(signalTimert *self); +internal void setIntervalSignalTimer(signalTimert *self, u64 interval); +/* TODO add prototypes */ + + +static signalTimert *theSignalTimerAddr = NULL; +internal void alarmSigaction(int signal, siginfo_t *si, void *arg); + +static struct itimerval it_val; + + +void initiateSignalTimer(signalTimert *self) { + + self->type = "signalTimer"; + if (!signalTimerF) { + signalTimerF = malloc(sizeof(signalTimerFunctionst)); + registerMethodsSignalTimer(signalTimerF); + pErrorNot0(atexit(finalizeSignalTimer)); + } + self->f = signalTimerF; + self->interval = 0; + theSignalTimerAddr = self; + + struct sigaction sa; + memset(&sa, 0, sizeof(struct sigaction)); + sigemptyset(&sa.sa_mask); + sa.sa_sigaction = alarmSigaction; + sa.sa_flags = SA_SIGINFO; + pTestErrorCmd(sigaction(SIGALRM, &sa, NULL) != 0, XFAILURE); + +} + +void registerMethodsSignalTimer(signalTimerFunctionst *f) { + + f->free = freeSignalTimer; + f->terminate = terminateSignalTimer; + f->toString = toStringSignalTimer; + f->duplicate = duplicateSignalTimer; + f->smash = smashSignalTimer; + f->finish = finishSignalTimer; + f->start = startSignalTimer; + f->stop = stopSignalTimer; + f->pause = pauseSignalTimer; + f->pauseProcess = pauseProcessSignalTimer; + f->restart = restartSignalTimer; + f->setInterval = setIntervalSignalTimer; + /* TODO add class functions */ +} + +void initiateAllocateSignalTimer(signalTimert **self) { + + if (self) { + (*self) = malloc(sizeof(signalTimert)); + if (*self) { + initiateSignalTimer(*self); + } + } +} + +void finalizeSignalTimer(void) { + + if (signalTimerF) { + free(signalTimerF); + signalTimerF = NULL; + } +} + +signalTimert* allocSignalTimer(void/* TODO change parameter to get the initial data for the object */) { + signalTimert *r = NULL; + + initiateAllocateSignalTimer(&r); + /* TODO copy data given in parameter to the object */ + return(r); +} + + +internal void freeSignalTimer(signalTimert *self) { + + /* TODO free internal data (not the structure holding the function pointers) */ + return; +} + +internal void terminateSignalTimer(signalTimert **self) { + + // stop SIGALARM + stopSignalTimer(*self); + theSignalTimerAddr = NULL; + + freeSignalTimer(*self); + free(*self); + *self = NULL; +} + + +internal char* toStringSignalTimer(signalTimert *self) { + + /* TODO convert object data to string */ + return(strdup("TODO - signalTimer")); +} + +internal signalTimert* duplicateSignalTimer(signalTimert *self) { + + //createAllocateSignalTimer(dup); + /* TODO COPY data */ + return NULL; +} + +internal void smashSignalTimer(signalTimert **self) { + + finishSignalTimer(self); +} + +internal void finishSignalTimer(signalTimert **self) { + + free(*self); + *self = NULL; +} + +internal bool startSignalTimer(signalTimert *self, u64 interval, void (*callback)(void *), void *args) { + + if (!callback || !interval) return false; + + self->interval = interval; + self->callback = callback; + self->args = args; + + it_val.it_value.tv_sec = interval/1000; + it_val.it_value.tv_usec = (interval*1000) % 1000000; + it_val.it_interval = it_val.it_value; + pTestErrorCmd(setitimer(ITIMER_REAL, &it_val, NULL) == -1, return false); + + return true; +} + + +internal void stopSignalTimer(signalTimert *self) { + // turn off / stop timer + it_val.it_value.tv_sec = 0; + it_val.it_value.tv_usec = 0; + it_val.it_interval = it_val.it_value; + setitimer(ITIMER_REAL, &it_val, NULL); +} + +internal void pauseSignalTimer(signalTimert *self) { + // turn off / stop timer + struct itimerval it_val; + it_val.it_value.tv_sec = 0; + it_val.it_value.tv_usec = 0; + it_val.it_interval = it_val.it_value; + setitimer(ITIMER_REAL, &it_val, NULL); +} + +internal void pauseProcessSignalTimer(signalTimert *self) { + pause(); +} + +internal void restartSignalTimer(signalTimert *self) { + setitimer(ITIMER_REAL, &it_val, NULL); +} + +internal void setIntervalSignalTimer(signalTimert *self, u64 interval) { + self->interval = interval; + it_val.it_value.tv_sec = interval/1000; + it_val.it_value.tv_usec = (interval*1000) % 1000000; + it_val.it_interval = it_val.it_value; + setitimer(ITIMER_REAL, &it_val, NULL); +} + +internal void alarmSigaction(int signal, siginfo_t *si, void *arg) { + theSignalTimerAddr->callback(theSignalTimerAddr->args); +} + +/* TODO add method implementations */ diff --git a/signalTimer.h b/signalTimer.h @@ -0,0 +1,97 @@ +#pragma once + +/* Add class methods and class data where there are the TODOs (TODO)*/ +#define startTimerG(obj, interval, callback, args) (obj)->f->start(obj, interval, callback, args) +#define stopG(obj) (obj)->f->stop(obj) +#define pauseG(obj) (obj)->f->pause(obj) +#define pauseProcessG(obj) (obj)->f->pauseProcess(obj) +#define restartG(obj) (obj)->f->restart(obj) +#define setIntervalG(obj, interval) (obj)->f->setInterval(obj, interval) + +/* Class signalTimer */ +typedef struct signalTimer signalTimert; + +/* for object inheriting signalTimer, cast to signalTimer to be able to use this class functions and generics*/ +#define cSignalTimer(self) ( (signalTimert*) self ) + +typedef void (*freeSignalTimerFt) (signalTimert *self); +typedef void (*terminateSignalTimerFt) (signalTimert **self); +typedef char* (*toStringSignalTimerFt) (signalTimert *self); +typedef signalTimert* (*duplicateSignalTimerFt) (signalTimert *self); +typedef void (*smashSignalTimerFt) (signalTimert **self); + +/** + * free signalTimer + */ +typedef void (*finishSignalTimerFt) (signalTimert **self); + +typedef bool (*startSignalTimerFt) (signalTimert *self, u64 interval, void (*callback)(void *), void *args); +typedef void (*stopSignalTimerFt) (signalTimert *self); +typedef void (*pauseSignalTimerFt) (signalTimert *self); +typedef void (*pauseProcessSignalTimerFt)(signalTimert *self); +typedef void (*restartSignalTimerFt) (signalTimert *self); +typedef void (*setIntervalSignalTimerFt) (signalTimert *self, u64 interval); +/* TODO add function typedef with pattern: functionNameClassTempleFt */ + +/** + * class functions + * allocated once for all objects + * + * freed with finalizeSignalTimer + */ + +/** + * use this define in child classes and add the new function after this class functions + * + * in this define, add the methods after <finishSignalTimerFt finish;> + * + * Example: + * #define RINGFUNCTIONST \n * SIGNALTIMERFUNCTIONST; \n * setSizeRingFt setSize + */ +#define SIGNALTIMERFUNCTIONST \ + startSignalTimerFt start;\ + stopSignalTimerFt stop;\ + pauseSignalTimerFt pause;\ + pauseProcessSignalTimerFt pauseProcess;\ + restartSignalTimerFt restart;\ + setIntervalSignalTimerFt setInterval; + /* TODO ADD METHODS AFTER <finishSignalTimerFt finish;> HERE */ + +typedef struct { + freeSignalTimerFt free; + terminateSignalTimerFt terminate; + toStringSignalTimerFt toString; + duplicateSignalTimerFt duplicate; + smashSignalTimerFt smash; + finishSignalTimerFt finish; + SIGNALTIMERFUNCTIONST; +} signalTimerFunctionst; + +/** + * class + */ +struct signalTimer { + const char *type; + signalTimerFunctionst *f; + + u64 interval; + void (*callback)(void *); + void *args; + /* TODO add class data */ +}; + +/* signalTimer */ + +#define createSignalTimer(obj) signalTimert obj; initiateSignalTimer(&obj) +#define createAllocateSignalTimer(obj) signalTimert *obj; initiateAllocateSignalTimer(&obj) + +void initiateSignalTimer(signalTimert *self); +void initiateAllocateSignalTimer(signalTimert **self); +void finalizeSignalTimer(void); + +/* initialize class methods, call registerMethodsSignalTimer from classes inheriting this class */ +void registerMethodsSignalTimer(signalTimerFunctionst *f); + +signalTimert* allocSignalTimer(/*TODO INIT DATA */); + +/* end class signalTimer*/ diff --git a/signalTimerInternal.h b/signalTimerInternal.h @@ -0,0 +1,6 @@ +#pragma once + +static signalTimerFunctionst *signalTimerF = NULL; + +/* TODO declare structs for private data and add a void pointer to the private data in the class declaration */ + diff --git a/test.c b/test.c @@ -0,0 +1,41 @@ +#! /usr/bin/env sheepy +/* or direct path to sheepy: #! /usr/local/bin/sheepy */ + +#include "libsheepyObject.h" +#include "signalTimer.h" + +int argc; char **argv; + +void callback(void *args) { + logI("timer callback"); +} + +int main(int ARGC, char** ARGV) { + + argc = ARGC; argv = ARGV; + + initLibsheepy(argv[0]); + + puts("C template"); + + createAllocateSignalTimer(sT); + sT->f->start(sT, 500, callback, NULL); + + i16 c = 0; + while(1) { + sT->f->pauseProcess(sT); + c++; + if (c == 4) break; + } + + sT->f->pause(sT); + nanoSleep(2000000000); + + sT->f->setInterval(sT, 100); + + while(1) { + sT->f->pauseProcess(sT); + } + + terminateG(sT); +}