[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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 (&current_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(&current_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: