Tenho alguns códigos como este que falharam uma vez no CI e uma vez localmente, embora não consiga reproduzi-lo de maneira confiável. O código é assim:
#include <stddef.h>
#include <signal.h>
#include <sys/time.h>
#include <time.h>
int main(void) {
// Ignore SIGALRM
signal(SIGALRM, SIG_IGN);
// Set a timer for every 100us
struct itimerval ival = {0};
ival.it_value.tv_usec = 100;
ival.it_interval.tv_usec = 100;
setitimer(ITIMER_REAL, &ival, NULL);
// Busy-wait 1s
time_t start = time(NULL);
while (time(NULL) <= start);
// Disable the timer
ival.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &ival, NULL);
// Restore the default SIGALRM disposition
signal(SIGALRM, SIG_DFL);
// Busy-wait 1s
start = time(NULL);
while (time(NULL) <= start);
return 0;
}
A falha que observo é o encerramento do processo devido a SIGALRM
(o shell diz "Despertador"). É possível que um SIGALRM
temporizador seja entregue após os setitimer()
retornos finais?
O texto POSIXsetitimer()
não é muito claro sobre a ordem entre os sinais e setitimer()
a desativação do temporizador.
Observei essa falha uma vez no Linux e uma vez no macOS .
Isso acabou não sendo um problema
setitimer()
, mas sim um problema ABA com meu código de registro do manipulador de sinal. Basicamente, eu tinha uma série de manipuladores de sinal para poder adicioná-los/removê-los dinamicamente durante o teste. Mas se você tem um loop fazendoenquanto o manipulador de sinal faz
Então a intercalação
A1, A2, B1, A3, A4, B2
fará com que ele pense que ambos os manipuladores estãoNULL
e aumente novamente o sinal fatal.