signalTimer

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

signalTimer.c (5881B)


      1 
      2 
      3 /* Add class methods and modify the base functions (free, duplicate, ...) where there are the TODOs (TODO)*/
      4 
      5 #include "libsheepyObject.h"
      6 #include "signalTimer.h"
      7 #include "signalTimerInternal.h"
      8 
      9 #include <stdlib.h>
     10 #include <string.h>
     11 #include <stdio.h>
     12 
     13 #include <sys/time.h> // setitimer
     14 #include <unistd.h>   // for pause
     15 #include <signal.h>   // signal
     16 
     17 void initiateSignalTimer(signalTimert *self);
     18 void registerMethodsSignalTimer(signalTimerFunctionst *f);
     19 void initiateAllocateSignalTimer(signalTimert **self);
     20 void finalizeSignalTimer(void);
     21 signalTimert* allocSignalTimer(void);
     22 internal void freeSignalTimer(signalTimert *self);
     23 internal void terminateSignalTimer(signalTimert **self);
     24 internal char* toStringSignalTimer(signalTimert *self);
     25 internal signalTimert* duplicateSignalTimer(signalTimert *self);
     26 internal void smashSignalTimer(signalTimert **self);
     27 internal void finishSignalTimer(signalTimert **self);
     28 
     29 internal bool startSignalTimer(signalTimert *self, u64 interval, void (*callback)(void *), void *args);
     30 internal void stopSignalTimer(signalTimert *self);
     31 internal void pauseSignalTimer(signalTimert *self);
     32 internal void pauseProcessSignalTimer(signalTimert *self);
     33 internal void restartSignalTimer(signalTimert *self);
     34 internal void setIntervalSignalTimer(signalTimert *self, u64 interval);
     35 /* TODO add prototypes */
     36 
     37 
     38 static signalTimert *theSignalTimerAddr = NULL;
     39 internal void alarmSigaction(int signal, siginfo_t *si, void *arg);
     40 
     41 static struct itimerval it_val;
     42 
     43 internal struct sigaction oldsa;
     44 
     45 void initiateSignalTimer(signalTimert *self) {
     46 
     47   self->type = "signalTimer";
     48   if (!signalTimerF) {
     49     signalTimerF            = malloc(sizeof(signalTimerFunctionst));
     50     registerMethodsSignalTimer(signalTimerF);
     51     pErrorNot0(atexit(finalizeSignalTimer));
     52   }
     53   self->f            = signalTimerF;
     54   self->interval     = 0;
     55   theSignalTimerAddr = self;
     56 
     57   struct sigaction sa;
     58   memset(&sa, 0, sizeof(struct sigaction));
     59   sigemptyset(&sa.sa_mask);
     60   sa.sa_sigaction = alarmSigaction;
     61   sa.sa_flags   = SA_SIGINFO;
     62   pTestErrorCmd(sigaction(SIGALRM, &sa, &oldsa) != 0, XFAILURE);
     63 
     64 }
     65 
     66 void registerMethodsSignalTimer(signalTimerFunctionst *f) {
     67 
     68   f->free         = freeSignalTimer;
     69   f->terminate    = terminateSignalTimer;
     70   f->toString     = toStringSignalTimer;
     71   f->duplicate    = duplicateSignalTimer;
     72   f->smash        = smashSignalTimer;
     73   f->finish       = finishSignalTimer;
     74   f->start        = startSignalTimer;
     75   f->stop         = stopSignalTimer;
     76   f->pause        = pauseSignalTimer;
     77   f->pauseProcess = pauseProcessSignalTimer;
     78   f->restart      = restartSignalTimer;
     79   f->setInterval  = setIntervalSignalTimer;
     80   /* TODO add class functions */
     81 }
     82 
     83 void initiateAllocateSignalTimer(signalTimert **self) {
     84 
     85   if (self) {
     86     (*self) = malloc(sizeof(signalTimert));
     87     if (*self) {
     88       initiateSignalTimer(*self);
     89     }
     90   }
     91 }
     92 
     93 void finalizeSignalTimer(void) {
     94 
     95   if (signalTimerF) {
     96     free(signalTimerF);
     97     signalTimerF = NULL;
     98   }
     99 }
    100 
    101 signalTimert* allocSignalTimer(void/* TODO change parameter to get the initial data for the object */) {
    102   signalTimert *r = NULL;
    103 
    104   initiateAllocateSignalTimer(&r);
    105   /* TODO copy data given in parameter to the object */
    106   return(r);
    107 }
    108 
    109 
    110 internal void freeSignalTimer(signalTimert *self) {
    111 
    112   /* TODO free internal data (not the structure holding the function pointers) */
    113   return;
    114 }
    115 
    116 internal void terminateSignalTimer(signalTimert **self) {
    117 
    118   // stop SIGALARM
    119   stopSignalTimer(*self);
    120   theSignalTimerAddr = NULL;
    121 
    122   freeSignalTimer(*self);
    123   free(*self);
    124   *self = NULL;
    125 }
    126 
    127 
    128 internal char* toStringSignalTimer(signalTimert *self) {
    129 
    130   /* TODO convert object data to string */
    131   return(strdup("TODO - signalTimer"));
    132 }
    133 
    134 internal signalTimert* duplicateSignalTimer(signalTimert *self) {
    135 
    136   //createAllocateSignalTimer(dup);
    137   /* TODO COPY data */
    138   return NULL;
    139 }
    140 
    141 internal void smashSignalTimer(signalTimert **self) {
    142 
    143   finishSignalTimer(self);
    144 }
    145 
    146 internal void finishSignalTimer(signalTimert **self) {
    147 
    148   free(*self);
    149   *self = NULL;
    150 }
    151 
    152 internal bool startSignalTimer(signalTimert *self, u64 interval, void (*callback)(void *), void *args) {
    153 
    154   if (!callback || !interval) return false;
    155 
    156   self->interval = interval;
    157   self->callback = callback;
    158   self->args     = args;
    159 
    160   it_val.it_value.tv_sec  = interval/1000;
    161   it_val.it_value.tv_usec = (interval*1000) % 1000000;
    162   it_val.it_interval      = it_val.it_value;
    163   pTestErrorCmd(setitimer(ITIMER_REAL, &it_val, NULL) == -1, return false);
    164 
    165   return true;
    166 }
    167 
    168 
    169 internal void stopSignalTimer(signalTimert *self) {
    170   // turn off / stop timer
    171   it_val.it_value.tv_sec  = 0;
    172   it_val.it_value.tv_usec = 0;
    173   it_val.it_interval      = it_val.it_value;
    174   setitimer(ITIMER_REAL, &it_val, NULL);
    175 }
    176 
    177 internal void pauseSignalTimer(signalTimert *self) {
    178   // turn off / stop timer
    179   struct itimerval it_val;
    180   it_val.it_value.tv_sec  = 0;
    181   it_val.it_value.tv_usec = 0;
    182   it_val.it_interval      = it_val.it_value;
    183   setitimer(ITIMER_REAL, &it_val, NULL);
    184 }
    185 
    186 internal void pauseProcessSignalTimer(signalTimert *self) {
    187   pause();
    188 }
    189 
    190 internal void restartSignalTimer(signalTimert *self) {
    191   setitimer(ITIMER_REAL, &it_val, NULL);
    192 }
    193 
    194 internal void setIntervalSignalTimer(signalTimert *self, u64 interval) {
    195   self->interval = interval;
    196   it_val.it_value.tv_sec  = interval/1000;
    197   it_val.it_value.tv_usec = (interval*1000) % 1000000;
    198   it_val.it_interval      = it_val.it_value;
    199   setitimer(ITIMER_REAL, &it_val, NULL);
    200 }
    201 
    202 internal void alarmSigaction(int signal, siginfo_t *si, void *arg) {
    203   theSignalTimerAddr->callback(theSignalTimerAddr->args);
    204   if (oldsa.sa_sigaction) oldsa.sa_sigaction(signal, si, arg);
    205   if (oldsa.sa_handler) oldsa.sa_handler(signal);
    206 }
    207 
    208 /* TODO add method implementations */
    209 
    210 bool checkLibsheepyVersionSignalTimer(const char *currentLibsheepyVersion) {
    211   return eqG(currentLibsheepyVersion, LIBSHEEPY_VERSION);
    212 }
    213