Timer & setjmp : comment réinitialiser un timer ?
Bonjour,
J'ai un soucis avec un timer, que je n'arrive pas à réinitialiser : je cherche à limiter le temps d'execution d'une fonction, et donc pour ça je pensais armer un timer, appeler setjmp, appeler la fonction, et si elle se finit bien, supprimer le timer et continuer le programme.
Dans le cas où ma fonction compute() prends trop de temps, on sort bien au bout du temps du timer et tout va bien.
Par contre, si compute() rend la main tout de suite, je n'arrive pas à annuler le timer....
Qu'est-ce que je fais de travers dans le code suivant ????
[Attention, n'oubliez pas le -lrt pour compiler avec gcc]
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/time.h>
#include <sys/types.h>
#include <setjmp.h>
timer_t timerid;
static jmp_buf buf;
struct itimerspec toto;
void time_handler (void)
{
long i;
printf ("debug in handler\n");
i = timer_gettime (timerid, &toto);
if (i == 0)
{
/* no more time */
printf ("debug in handler 2 i %ld\n", i);
longjmp (buf, 1);
}
printf ("debug in handler 3 , i %ld\n", i);
}
void compute (void)
{
int i = 0;
int j = 0;
return;
while (1)
{
i = j++;
}
}
int main (void)
{
struct itimerspec max_time;
struct sigaction signal_action;
struct sigevent signal_event;
int retour = 0;
max_time.it_interval.tv_sec = 0;
max_time.it_interval.tv_nsec = 0;
max_time.it_value.tv_sec = 2;
max_time.it_value.tv_nsec = 0;
signal_action.sa_handler = (void*)time_handler;
sigemptyset (&signal_action.sa_mask);
signal_action.sa_flags = 0;
errno = 0;
retour = sigaction (SIGUSR1, &signal_action, (struct sigaction *)NULL);
if (retour == -1)
{
fprintf (stderr, "Error %d on sigaction : %s\n", errno, strerror(errno));
exit (-1);
}
signal_event.sigev_notify = SIGEV_SIGNAL;
signal_event.sigev_signo = SIGUSR1;
if (timer_create (CLOCK_REALTIME, &signal_event, &timerid) == -1)
{
fprintf (stderr, "Error %d on timer creation : %s\n", errno, strerror(errno));
exit (-1);
}
printf ("before settime\n");
timer_settime (timerid, 0, &max_time, (struct itimerspec*)NULL);
if (setjmp(buf) == 0)
{
compute();
timer_settime (timerid, 0, 0, (struct itimerspec*)NULL);
};
printf ("after compute\n");
sleep (5);
printf ("after sleep\n");
return EXIT_SUCCESS;
} |
Sortie attendue :
Citation:
before settime
after compute
after sleep
Sortie constatée :
Citation:
before settime
after compute
debug in handler
debug in handler 2 i 0
after compute
after sleep