summaryrefslogtreecommitdiff
path: root/src/timer.c
diff options
context:
space:
mode:
authordamiano1998-04-09 13:55:38 +0000
committerdamiano1998-04-09 13:55:38 +0000
commit6d4a1d57836737d2e7ac8b4e3f19b0ba736e3981 (patch)
tree8c36fa43b5e19ce4332a3ee4c7408e89d04e8970 /src/timer.c
parent6143ab5fb9ee7f32f6f779c06c176957fac8c3f2 (diff)
downloadivy-c-6d4a1d57836737d2e7ac8b4e3f19b0ba736e3981.zip
ivy-c-6d4a1d57836737d2e7ac8b4e3f19b0ba736e3981.tar.gz
ivy-c-6d4a1d57836737d2e7ac8b4e3f19b0ba736e3981.tar.bz2
ivy-c-6d4a1d57836737d2e7ac8b4e3f19b0ba736e3981.tar.xz
Move des fichiers dans src
Diffstat (limited to 'src/timer.c')
-rw-r--r--src/timer.c160
1 files changed, 160 insertions, 0 deletions
diff --git a/src/timer.c b/src/timer.c
new file mode 100644
index 0000000..a1fb791
--- /dev/null
+++ b/src/timer.c
@@ -0,0 +1,160 @@
+/* Module de gestion des timers autour d'un select */
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/timeb.h>
+#include <stdlib.h>
+#include <time.h>
+#include <memory.h>
+#ifdef WIN32
+#include <windows.h>
+#endif
+#include "list.h"
+#include "timer.h"
+
+#define BIGVALUE 2147483647
+#define MILLISEC 1000
+
+static struct timeval *timeoutptr = NULL;
+static struct timeval selectTimeout = { BIGVALUE, 0 };
+/* la prochaine echeance */
+static unsigned long nextTimeout = BIGVALUE;
+
+struct _timer {
+ struct _timer *next;
+ int repeat;
+ unsigned long period;
+ unsigned long when;
+ TimerCb callback;
+ void *user_data;
+ }Timer;
+
+/* liste des timers */
+TimerId timers = NULL;
+
+static long currentTime()
+{
+ struct timeval tv;
+ unsigned long current;
+ gettimeofday (&tv, 0);
+ current = 1000 * tv.tv_sec + tv.tv_usec / 1000;
+ return current;
+
+#if 0
+ unsigned long current;
+ current = clock();
+ return current;
+#endif
+}
+static void SetNewTimeout( unsigned long current, unsigned long when )
+{
+ unsigned long time;
+ time = when - current;
+ nextTimeout = when;
+ selectTimeout.tv_sec = time / MILLISEC;
+ selectTimeout.tv_usec = (time - selectTimeout.tv_sec* MILLISEC) * MILLISEC;
+ if ( timeoutptr == NULL )
+ timeoutptr = &selectTimeout;
+ /*printf("New timeout %lu\n", time );*/
+}
+static void AdjTimeout(unsigned long current)
+{
+ unsigned long newTimeout;
+ TimerId timer;
+ if ( timers )
+ {
+ /* recherche de la plus courte echeance dans la liste */
+ newTimeout = timers->when ; /* remise a la premiere valeur */
+ LIST_EACH( timers , timer )
+ {
+ if ( timer->when < newTimeout )
+ newTimeout = timer->when;
+
+ }
+ SetNewTimeout( current, newTimeout );
+ }
+ else
+ {
+ timeoutptr = NULL;
+ }
+}
+
+/* API */
+
+TimerId TimerRepeatAfter( int count, long time, TimerCb cb, void *user_data )
+{
+ unsigned long stamp;
+ TimerId timer;
+
+ /* si y a rien a faire et ben on fait rien */
+ if ( cb == NULL ) return NULL;
+
+ LIST_ADD( timers, timer )
+ if ( timer )
+ {
+ timer->repeat = count;
+ timer->callback = cb;
+ timer->user_data = user_data;
+ stamp = currentTime();
+ timer->period = time;
+ timer->when = stamp + time;
+ if ( (timer->when < nextTimeout) || (timeoutptr == NULL))
+ SetNewTimeout( stamp, timer->when );
+ }
+ return timer;
+}
+void TimerRemove( TimerId timer )
+{
+ unsigned long stamp;
+ if ( !timer ) return;
+ LIST_REMOVE( timers, timer );
+ stamp = currentTime();
+ AdjTimeout(stamp);
+}
+void TimerModify( TimerId timer, long time )
+{
+ unsigned long stamp;
+ if ( !timer ) return;
+
+ stamp = currentTime();
+ timer->period = time;
+ timer->when = stamp + time;
+ AdjTimeout(stamp);
+}
+/* Interface avec select */
+
+struct timeval *TimerGetSmallestTimeout()
+{
+ return timeoutptr;
+}
+
+void TimerScan()
+{
+ unsigned long stamp;
+ TimerId timer;
+ TimerId next;
+ unsigned long delta;
+ int timer_echu = 0;
+
+ stamp = currentTime();
+ /* recherche des timers echu dans la liste */
+ LIST_EACH_SAFE( timers , timer, next )
+ {
+ if ( timer->when <= stamp )
+ {
+ timer_echu++;
+ delta = stamp - timer->when;
+ /* call callback */
+ (*timer->callback)( timer, timer->user_data, delta );
+ if ( timer->repeat == TIMER_LOOP || --(timer->repeat) )
+ {
+ timer->when = stamp + timer->period;
+ }
+ else
+ {
+ LIST_REMOVE( timers, timer );
+ }
+ }
+ }
+ /* recalcul du prochain timeout */
+ AdjTimeout( stamp );
+}