Re: use alarm() to achieve timeout.



On Dec 18, 2:42 am, David Schwartz <dav...@xxxxxxxxxxxxx> wrote:
On Dec 16, 7:27 pm, hellog...@xxxxxxxxx wrote:

Thanks for your reply. So you mean what I concern is right and the
implementation of timeout using alarm() from
UNP(<<unix network programming ,3rd, by Richard stevens>>)
is not perfect(the code I wrote above is from UNP)

You are correct. That code has a race condition.

just because of the small window between alarm() and recvfrom().
then could you please show me a correct solution to implement
timeout using alarm() when doing socket i/o?

I don't have the code handy, but the basic idea is to have the signal
handler call longjmp. You only call the function you want to timeout
if 'setjmp' returns zero. Since the signal handler calls 'longjmp',
the signal handler will ensure 'setjmp' does not return zero. So there
is no way you can call 'recvfrom' (or whatever) after the signal has
fired.

DS

I think the following is possibly a correct solution


static sigjmp_buf jmpbuf;// global data

{//inside a function
...
struct sigaction act;
act.sa_handler=sig_alrm;
sigemptyset(&act.sa_mask);
act.sa_flags=0;
// now we do not need the following line
// because we're using siglongjmp
// act.sa_flags |=SA_INTERRUPT;
sigaction(SIGALRM,&act,NULL);

if(sigsetjmp(jmpbuf,1)){
printf("timeout when trying to read\n");
} else{
alarm(5);// will timeout in 5 seconds
recvfrom(...);
alarm(0);// turn off the alarm
}
...
}

void sig_alrm(int signo)
{
siglongjmp(jmpbuf,1);
}
.