Timers
Hi All,
I've got a problem that someone may have some idea on. I'm working with nanogui and ran into a timer problem and may be in the implementation of the linux timer. I'm using the 2.6 kernal.
It appears that my timer events are only fired when I have a debug print statement in it (in the GsSelect function I added in the code snip below). Without it it appears that either the function is not being called or the timers are never fired. All the necessary conditions for the function call is met to my knowledge so my conclusion is the timer expiration is not being fired. I would admit I haven't done a trace but it might be something as simple as a compiler flag, include file or some change in the linux timer.
I've added a few code snips below.
Thanks
MWTIMER *GdAddPeriodicTimer(MWTIMEOUT timeout, MWTIMERCB callback, void *arg)
{
MWTIMER *newtimer;
if(!(newtimer = malloc(sizeof(MWTIMER)))) return NULL;
gettimeofday (¤t_time, NULL);
if (timerlist) timerlist->prev = newtimer;
calculate_timeval (&newtimer->timeout, timeout);
newtimer->callback = callback;
newtimer->arg = arg;
newtimer->next = timerlist;
newtimer->prev = NULL;
newtimer->type = MWTIMER_PERIODIC;
newtimer->period = timeout;
timerlist = newtimer;
return newtimer;
}
MWBOOL GdGetNextTimeout(struct timeval *tv, MWTIMEOUT timeout)
{
signed long i, lowest_timeout;
MWTIMER *t = timerlist;
if(!timeout && !timerlist) return FALSE;
gettimeofday(¤t_time, NULL);
if(timeout) {
calculate_timeval(&mainloop_timeout, timeout);
lowest_timeout = time_to_expiry(&mainloop_timeout);
} else {
lowest_timeout = time_to_expiry(&t->timeout);
mainloop_timeout.tv_sec = -1;
t = t->next;
}
while(t) {
i = time_to_expiry(&t->timeout);
if(i < lowest_timeout) lowest_timeout = i;
t = t->next;
}
if(lowest_timeout <= 0) {
tv->tv_sec = 0;
tv->tv_usec = 0;
} else {
tv->tv_sec = lowest_timeout / 1000;
tv->tv_usec = (lowest_timeout % 1000) * 1000;
}
return TRUE;
}
void
GsSelect(GR_TIMEOUT timeout)
{
fd_set rfds;
int e;
int setsize = 0;
struct timeval tout;
struct timeval *to;
#if HAVE_VNCSERVER
#if VNCSERVER_PTHREADED
int dummy;
#else
rfbClientIteratorPtr i;
rfbClientPtr cl;
#endif
#endif
/* perform pre-select duties, if any*/
if(rootwp->psd->PreSelect)
rootwp->psd->PreSelect(rootwp->psd);
/* handle client socket connections*/
FD_SET(un_sock, &rfds);
if (un_sock > setsize) setsize = un_sock;
curclient = root_client;
while(curclient) {
if(curclient->waiting_for_event && curclient->eventhead) {
curclient->waiting_for_event = FALSE;
GrGetNextEventWrapperFinish(curclient->id);
return;
}
FD_SET(curclient->id, &rfds);
if(curclient->id > setsize) setsize = curclient->id;
curclient = curclient->next;
}
#if HAVE_VNCSERVER
#if VNCSERVER_PTHREADED
/* Add file vnc thread fd. This is useful to force handling of
events generated by the VNC thread.
*/
FD_SET( vnc_thread_fd, &(rfds) );
if ( vnc_thread_fd > setsize )
setsize = vnc_thread_fd;
#else
/* Add all VNC open sockets to nano-X select set */
FD_SET( rfbScreen->rfbListenSock, &(rfds) );
if ( rfbScreen->rfbListenSock > setsize )
setsize = rfbScreen->rfbListenSock;
FD_SET( rfbScreen->httpListenSock, &(rfds) );
if ( rfbScreen->httpListenSock > setsize )
setsize = rfbScreen->httpListenSock;
i = rfbGetClientIterator(rfbScreen);
cl = rfbClientIteratorNext(i);
while ( cl ) {
if ( cl->sock >= 0 ) {
FD_SET( cl->sock, &(rfds) );
if ( cl->sock > setsize )
setsize = cl->sock;
}
cl = rfbClientIteratorNext(i);
}
rfbReleaseClientIterator(i);
#endif
#endif /* HAVE_VNCSERVER*/
/* Set up the timeout for the main select(): */
if (timeout == (GR_TIMEOUT) -1L) {
/* poll*/
tout.tv_sec = 0;
tout.tv_usec = 0;
to = &tout;
} else {
EPRINTF("Go get next timeout\n");
if (GdGetNextTimeout(&tout, timeout))
to = &tout;
else
to = NULL;
}
/* Wait for some input on any of the fds in the set or a timeout: */
if((e = select(setsize+1, &rfds, NULL, NULL, to)) > 0) {
/* If data is present on the mouse fd, service it: */
if(mouse_fd >= 0 && FD_ISSET(mouse_fd, &rfds))
while(GsCheckMouseEvent())
continue;
/* If data is present on the keyboard fd, service it: */
if( (keyb_fd >= 0 && FD_ISSET(keyb_fd, &rfds))
#ifdef MW_FEATURE_TWO_KEYBOARDS
|| (keyb2_fd >= 0 && FD_ISSET(keyb2_fd, &rfds))
#ifdef MW_FEATURE_TWO_KEYBOARDS
|| (keyb2_fd >= 0 && FD_ISSET(keyb2_fd, &rfds))
#endif
)
while(GsCheckKeyboardEvent())
continue;
#if HAVE_VNCSERVER && VNCSERVER_PTHREADED
if ( vnc_thread_fd >= 0 && FD_ISSET(vnc_thread_fd, &rfds) )
/* Read from vnc pipe */
read( vnc_thread_fd, &dummy, sizeof(int));
#endif
/* If a client is trying to connect, accept it: */
if(FD_ISSET(un_sock, &rfds))
GsAcceptClient();
/* If a client is sending us a command, handle it: */
curclient = root_client;
while(curclient) {
GR_CLIENT *curclient_next;
/* curclient may be freed in GsDropClient*/
curclient_next = curclient->next;
if(FD_ISSET(curclient->id, &rfds))
GsHandleClient(curclient->id);
curclient = curclient_next;
}
}
else if (e == 0) {
GdTimeout();
} else
if(errno != EINTR)
EPRINTF("Select() call in main failed\n");
}
_______________________________________________
Join Excite! - http://www.excite.com
The most personalized portal on the Web!
Reply to: