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:
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);
+}