示例#1
0
void SipImpApp::process(void)
{
	resip_assert(sipStack);
	
	if ( !tuIM )
	{
		return;
	}
	
	resip_assert(tuIM);

	FdSet fdset; 
	sipStack->buildFdSet(fdset);

	int  err = fdset.selectMilliSeconds( 0 );
	if ( err == -1 )
	{
		int e = errno;
		resip_assert(0);
		//InfoLog(<< "Error " << e << " " << strerror(e) << " in select");
	}
	//InfoLog(<< "Select returned");

	//DebugLog ( << "Try TO PROCESS " );
	sipStack->process(fdset);

	tuIM->process();
}
示例#2
0
void SIPEngine::run()
{
    FdSet fdset;
    this->mSipStack->buildFdSet(fdset);
    int err = fdset.selectMilliSeconds(resipMin((int)mSipStack->getTimeTillNextProcessMS(), 200));
    this->mSipStack->process(fdset);
    while(this->mDum->process());
}
示例#3
0
bool
TuPresSvr::process()
{

    bool done = 0;
    FdSet fdset;
    mStack->buildFdSet(fdset);
//    int err = fdset.selectMilliSeconds(0);
    int err = fdset.selectMilliSeconds(100);
    assert( err != -1 );

    mStack->process(fdset);

    SipMessage* msg = (mStack->receive());
    if (msg)
    {
      if (msg->isRequest())
      {
	if (msg->header(h_RequestLine).getMethod() == SUBSCRIBE )
	{
          processSubscribe(msg);
	}
	else if (msg->header(h_RequestLine).getMethod() == REGISTER )
	{
	  processPublish(msg);
	}
	else if (msg->header(h_RequestLine).getMethod() == OPTIONS )
	{
          auto_ptr<SipMessage> resp(
               Helper::makeResponse(*msg,500,"You Shot Me!")); 
          mStack->send(*resp);
	  done = 1;
	}
	else if (msg->header(h_RequestLine).getMethod() == PUBLISH)
	{
           processPublish(msg);
	}
	else
	{
          auto_ptr<SipMessage> resp(Helper::makeResponse(*msg,501,"")); 
          mStack->send(*resp);
	}
      }
      else
      {
	/*
	 Nope - dialog key is currently overscoped to requests - bad.
	assert(msg->isResponse());
	if (msg->header(h_CSeq).method()==NOTIFY)
	  mDialogMgr.dispatchNotifyResponse(msg);
         */
      }
      delete msg;
    } else {
      mDialogMgr.processExpirations();
    }
    return done;
}
示例#4
0
/*
 * Under win32, it seems that fd is not allocated continously.
 * Sorry for windows guys:'(
 */
bool SocketRegistryImpl::poll(time_t now)
{
	FdSet fdset;
	int fds[FD_SIZE];
	int nfds = 0;
	FD_ENTRY *e;

	// Set in the fd_set from 0 to maxfd
	for (e = fdTable + maxfd; e >= fdTable; e--) {
		if (e->fd < 0)
			continue;

		// Check timeout
		if (e->timeout && e->timeout <= now) {
			// Reset timer
			e->timeout = 0;
			e->listener->onSocketTimeout();
	
		} else if (e->event) {
			fdset.setFd(e->fd, e->event);
			fds[nfds++] = e->fd;
		}
	}

	int n = fdset.poll();
	if (n < 0)
		return false;

	// Returns if no sockets event
	if (n == 0)
		return true;

	// Dispatch socket events
	for (int i = 0; i < nfds; i++) {
		int events = fdset.getEventsReady(i, fds[i]);
		e = fdTable + fds[i];

		if (events & SOCKET_READ) {
			// Do not poll on this fd any more if an error occurs
			if (!e->listener->onSocketRead()) {
				e->event = 0;
				continue;
			}
		}
		if (events & SOCKET_WRITE) {
			// We remove write event mask here. clients may add it again
			// in onSocketWrite()
			removeEvent(e->fd, SOCKET_WRITE);
			e->timeout = 0;
			e->listener->onSocketWrite();
		}
	}

	return true;
}
void testUnixSelect() { // won't work on win32
    FdSet rfds;
    rfds.add(0);
    printf("enter some text: \n");
    try {
        int count = select(&rfds, 0, 0, true, 3);
        //        int count = select(&rfds);
        // it better have this...
        if (count > 0) {
            if (rfds.has(0))
                printf("got input\n");
        }
        else
            printf("timeout\n");
    } catch (const SystemError& e) {
        printf(e.what());
    }
}
示例#6
0
void d4Thread::_select_io (const TimeSpec* due)
{
    assert(     _msgpipe_rfd >= 0);
    assert(sched.msgpipe_wfd >= 0);

    for (;;) {

        /******************************
            file descriptors sets
        ******************************/

        _fdset[IO_read ].zero();
        _fdset[IO_write].zero();
        _fdset[IO_error].zero();

        for (FdModeSid_Map::iterator i = _fms_map.begin(); i != _fms_map.end(); ++i) {
            EvIO*   evio = (*i).second;
            if (evio->active()) {
                _fdset[evio->mode()].add_fd(evio->fd());
            }
        }

        // highest descriptor including '_msgpipe_rfd' which...
        const int max_fd = max(_fdset[IO_read ].max_fd,
                           max(_fdset[IO_write].max_fd,
                           max(_fdset[IO_error].max_fd,
                               _msgpipe_rfd)));     // will be add_fd()'ed after assert(s)

#if COEXX_SELECT_USE_FD_SET
        // check if      _msgpipe_rfd not clobbered
        assert(0 == FD_ISSET(     _msgpipe_rfd, &_fdset[IO_read ].lval));
        assert(0 == FD_ISSET(     _msgpipe_rfd, &_fdset[IO_write].lval));
        assert(0 == FD_ISSET(     _msgpipe_rfd, &_fdset[IO_error].lval));
        // check if sched.msgpipe_wfd not clobbered
        assert(0 == FD_ISSET(sched.msgpipe_wfd, &_fdset[IO_read ].lval));
        assert(0 == FD_ISSET(sched.msgpipe_wfd, &_fdset[IO_write].lval));
        assert(0 == FD_ISSET(sched.msgpipe_wfd, &_fdset[IO_error].lval));
#else
        // align all lvec(s) to the longest, enlarged to assumption made in checks
        {
            int max_fd_and_pipes = max(max_fd,  // _msgpipe_rfd included in max_fd
                                       sched.msgpipe_wfd);
            _fdset[IO_read ].fit_fd(max_fd_and_pipes);
            _fdset[IO_write].fit_fd(max_fd_and_pipes);
            _fdset[IO_error].fit_fd(max_fd_and_pipes);
        }

        // check if      _msgpipe_rfd not clobbered
        {
            int     word =         _msgpipe_rfd / NFDBITS;
            fd_mask mask = 1UL << (_msgpipe_rfd % NFDBITS);
            assert(0 == (_fdset[IO_read ].lvec[word] & mask));
            assert(0 == (_fdset[IO_write].lvec[word] & mask));
            assert(0 == (_fdset[IO_error].lvec[word] & mask));
        }
        // check if sched.msgpipe_wfd not clobbered
        {
            int     word =         sched.msgpipe_wfd / NFDBITS;
            fd_mask mask = 1UL << (sched.msgpipe_wfd % NFDBITS);
            assert(0 == (_fdset[IO_read ].lvec[word] & mask));
            assert(0 == (_fdset[IO_write].lvec[word] & mask));
            assert(0 == (_fdset[IO_error].lvec[word] & mask));
        }
#endif

        // finally add '_msgpipe_rfd'
        _fdset[IO_read].add_fd(_msgpipe_rfd);

        /******************************
                    timeout
        ******************************/

        struct timeval  tmo;

        if (NULL != due) {
            TimeSpec    delta = *due - get_current_time();
            if (delta > TimeSpec::ZERO()) {
                delta += TimeSpec(0, 999);  // ns(s) to us(s) round up
                tmo.tv_sec  = delta.tv_sec;
                tmo.tv_usec = delta.tv_nsec / 1000;
            }
            else {  // polling
                tmo.tv_sec  = 0;
                tmo.tv_usec = 0;
            }
        }

        /******************************
                    select
        ******************************/

        int result = select(max_fd + 1,
                            _fdset[IO_read ].sel_set(),
                            _fdset[IO_write].sel_set(),
                            _fdset[IO_error].sel_set(),
                            (due ? &tmo : NULL));

        if (result == -1) {

            if (errno == EINTR) {

                /*
                 * From POSIX `select' page
                 * (http://www.opengroup.org/onlinepubs/9699919799/):
                 * On failure, the objects pointed to by the readfds,
                 * writefds, and errorfds arguments shall not be modified.
                 * If the timeout interval expires without the specified
                 * condition being true for any of the specified file
                 * descriptors, the objects pointed to by the readfds,
                 * writefds, and errorfds arguments shall have all bits set
                 * to 0.
                 *
                 * From Linux `select' manpage:
                 * On error, -1 is returned, and errno is set appropriately;
                 * the  sets  and  timeout become undefined, so do not rely
                 * on their contents after an error.
                 *
                 **/

                continue;       // goto (file descriptors sets)
            }

            //
            // diagnostics on EBADF and possibly EINVAL
            //
            int last_errno = errno;
            {
                char    errbuf[1024];
                // _msgpipe_rfd
                assert(_msgpipe_rfd >= 0);
                _fdset[IO_read].zero();
                _fdset[IO_read].add_fd(_msgpipe_rfd);
                struct timeval  no_wait = {0, 0};
                if (select(_msgpipe_rfd + 1, _fdset[IO_read].sel_set(), NULL, NULL, &no_wait) == -1) {
                    sprintf(errbuf, "select(internal-read-pipe-FD=%d)", _msgpipe_rfd);
                    perror(errbuf);
                }
                // user's fd(s)
                for (FdModeSid_Map::iterator i = _fms_map.begin(); i != _fms_map.end(); ++i) {
                    EvIO*   evio = (*i).second;
                    if (evio->active()) {
                        int fd = evio->fd();
                        assert(fd >= 0);
                        IO_Mode mode = evio->mode();
                        assert(mode >= 0 && mode < 3);
                        fd_set* selset[3] = {NULL, NULL, NULL};
                        FdSet*  oneset = &_fdset[mode];
                        oneset->zero();
                        oneset->add_fd(fd);
                        selset[mode] = oneset->sel_set();
                        struct timeval  no_wait = {0, 0};
                        if (select(fd + 1, selset[0], selset[1], selset[2], &no_wait) == -1) {
                            sprintf(errbuf, "select(FD=%d, MODE=%d, EV=%s)", fd, int(mode), evio->name().c_str());
                            perror(errbuf);
                        }
                    }
                }
            }
            errno = last_errno;
            perror("select");
            abort();
        }

        /******************************
                update (guarded)
        ******************************/

        // --@@--
        Mutex::Guard    guard(sched.mutex);

        _pqueue_pending_events();

        _timestamp = get_current_time();

        if (NULL != due && _timestamp >= *due) {
            _pqueue_expired_alarms();
        }

        if (result > 0) {

            // read a byte from the notification pipe
            if (_fdset[IO_read].fd_isset(_msgpipe_rfd)) {

                char    buf[16];
                ssize_t nbytes = read(_msgpipe_rfd, buf, 8);    // try 8, expected 1

                if (nbytes == -1) {
                    if (errno == EINTR || errno == EAGAIN) {
                        continue;       // goto (file descriptors sets)
                    }
                    perror("read(pipe)");
                    abort();
                }
                else {
                    if (nbytes != 1) {
                        for (int i = 0; i < nbytes; ++i)
                            buf[i] = buf[i] == '@' ? '@' : '.';
                        (cerr << "read(pipe): " << nbytes
                              << " bytes \"").write(buf, nbytes) << "\" read!" << endl;
                        abort();
                    }
                    sched.msgpipe_flag = 0;     // pipe emptied
                }

                -- result;
            }

            //
            // _pqueue_io_events
            //
            if (result > 0) {

                if (sched.msgpipe_flag) {
                    /*
                     * `msgpipe' might not luck into the select altogether with other
                     * descriptors, but definitely should do the next time.
                     * If the pipe has been signalled I increment the flag in order to
                     * isolate a potential application bug which emptying the
                     * pipe breaks its signalling capability.
                     */
                    sched.msgpipe_flag ++;
                }
                if (sched.msgpipe_flag > 2) {
                    /*
                     * If tests confirm this never occurs, or if so, only due to a bug
                     * as stated in the comment above, remove the following
                     * assert completely or raise an exception.
                     */
                    assert(sched.msgpipe_flag <= 2);
                    sched.msgpipe_flag = 0;
                }

                for (FdModeSid_Map::iterator i = _fms_map.begin(); i != _fms_map.end(); ++i) {
                    EvIO*   evio = (*i).second;
                    if (evio->active() && _fdset[evio->mode()].fd_isset(evio->fd())) {
                        _pqueue.put_tail(evio);
                    }
                }
            }
        }

        //
        // check the predicate
        //
        if (! _pqueue.empty()) {
            sched.state = Sched::BUSY;
            return;
        }

    } ///// for (;;) -- file descriptors sets
}