⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 poll.cxx

📁 RTP协议
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/* ==================================================================== * The Vovida Software License, Version 1.0  *  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *  * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. *  * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. *  * 3. The names "VOCAL", "Vovida Open Communication Application Library", *    and "Vovida Open Communication Application Library (VOCAL)" must *    not be used to endorse or promote products derived from this *    software without prior written permission. For written *    permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor *    may "VOCAL" appear in their name, without prior written *    permission of Vovida Networks, Inc. *  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. *  * ==================================================================== *  * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc.  For more information on Vovida Networks, Inc., please see * <http://www.vovida.org/>. * */static const char* const Poll_cxx_Version =     "$Id: Poll.cxx,v 1.22 2002/06/25 17:01:25 bko Exp $";#include "global.h"#include "Poll.hxx"#include "Protocol.hxx"#include "FileDescriptor.hxx"#include "TransportCommon.hxx"#include "SystemException.hxx"#include "SystemStatus.hxx"#include "ConnectionBrokenException.hxx"#include "ProtocolException.hxx"#include "IPAddress.hxx"#include "Lock.hxx"#include "VLog.hxx"#include <cerrno>#include <iomanip>using Vocal::Transport::Poll;using Vocal::Transport::Protocol;using Vocal::Transport::pollfdLess;using Vocal::Transport::ConnectionBrokenException;using Vocal::IO::FileDescriptor;using Vocal::IO::file_descriptor_t;using Vocal::IO::Pipe;using Vocal::Process::Lock;using Vocal::Logging::VLog;using Vocal::SystemException;using Vocal::ReturnCode;using Vocal::SUCCESS;Poll::EventType    Poll::Incoming = 0x01;Poll::EventType    Poll::Outgoing = 0x02;Poll::EventType    Poll::Priority = 0x04;#if defined(WIN32) || defined(__APPLE__)// TODOint poll(pollfd *, unsigned int, int){    assert(0);    return 0;}#endifPoll::Poll()    :	myProtocolsChanged(false),	myInterruptCount(0){    myInterruptor.writeFD().setBlocking();    myInterruptor.readFD().setNonblocking();        // Add interruptor to poll file descriptor list. We are marking the    // protocols and unchanged, so that they won't get reloaded.    //    addInterruptorToFds();}Poll::~Poll(){}void	    	    Poll::registerFD(    const FileDescriptor &      fd,     EventType                   flag,    Protocol                *   protocol){    const string    fn("Poll::registerFD");    VLog    	    log(fn);    pollfd  	    newPollFd;        newPollFd.fd = fd.getFD();    newPollFd.events = newPollFd.revents = 0;        string  	eventNames;    bool    	awaitingSomething = false;        if ( flag & Incoming )    {    	newPollFd.events |= POLLIN;	eventNames += " POLLIN";	awaitingSomething = true;    }    if ( flag & Outgoing )    {    	newPollFd.events |= POLLOUT;	eventNames += " POLLOUT";	awaitingSomething = true;    }    if ( flag & Priority )    {    	newPollFd.events |= POLLPRI;	eventNames += " POLLPRI";	awaitingSomething = true;    }        if ( !awaitingSomething )    {    	VDEBUG(log) << fn << ": not awaiting any notifications, unregistering."	    	    << VDEBUG_END(log);		        	unregisterFD(fd);	return;    }            ProtocolMap::iterator   it = myProtocols.find(newPollFd);        if ( it != myProtocols.end() )    {    	// This may be an update. If necessary, replace the pollfd, 	// effectively reseting the events.	//	if ( it->first.events != newPollFd.events )	{	    // The whole pollfd is being used as a key in the pair, but 	    // looking more closely, only the file descriptor is being 	    // keyed off of. If we are here, the file descriptors 	    // (i.e. the true keys) are the same, but the events may 	    // be different. So casting the key portion of the pair to 	    // a non const pollfd is ok.	    //	    // This is the penalty I am paying for storing data in	    // the key.	    //	    pollfd & pollFd = const_cast<pollfd &>(it->first);            pollFd = newPollFd;	    myProtocolsChanged = true;	}    }    else     {    	// The is a first time registration. Add the poll file	// descriptor / protocol pair. 	//    	myProtocols[newPollFd] = protocol;	myProtocolsChanged = true;    }    VDEBUG(log) << fn << "\n\t" << fd    	    	<< "\n\tprotocols changed = " << ( myProtocolsChanged ? "true" : "false" )    	    	<< "\n\tevents: " << eventNames    	    	<< VDEBUG_END(log);    VVERBOSE(log) << fn << ": " << *this << VVERBOSE_END(log);}void	    	    Poll::updateFD(    const FileDescriptor    &   fd,     EventType                   flag,    Protocol                *   protocol){    registerFD(fd, flag, protocol);}void	    	    Poll::unregisterFD(const FileDescriptor & fd){    const string    fn("Poll::unregisterFD");    VLog    	    log(fn);    pollfd  	pollFd;    pollFd.fd = fd.getFD();    bool    removed = false;            ProtocolMap::iterator   it = myProtocols.find(pollFd);    if ( it != myProtocols.end() )    {    	// Found it, so let's remove it.	//    	myProtocols.erase(it);	myProtocolsChanged = true;	removed = true;    }    VDEBUG(log) << fn << "\n\t" << fd    	    	<< "\n\tprotocols changed = " << ( myProtocolsChanged ? "true" : "false" )		<< "\n\tremoved = " << ( removed ? "true" : "false" )    	    	<< VDEBUG_END(log);    VVERBOSE(log) << fn << ": " << *this << VVERBOSE_END(log);}void	    	    Poll::registerProtocol(Protocol & protocol){    EventType   flag = 0;    if ( protocol.awaitIncoming() )    {    	flag |= Incoming;    }    if ( protocol.awaitOutgoing() )    {    	flag |= Outgoing;    }    if ( protocol.awaitPriority() )    {    	flag |= Priority;    }    registerFD(protocol.getFileDescriptor(), flag, &protocol);}void	    	    Poll::updateProtocol(Protocol & protocol){    registerProtocol(protocol);}void	    	    Poll::unregisterProtocol(Protocol & protocol){    unregisterFD(protocol.getFileDescriptor());}int 	    	    Poll::poll(int timeout)throw ( Vocal::SystemException ){    const string    fn("Poll::poll");    VLog    	    log(fn);        // Recreate the poll file descriptor if needed.    //    if ( myProtocolsChanged )    {    	VDEBUG(log) << fn << ": protocols changed, updating." << VDEBUG_END(log);	    	myFds.clear();	addInterruptorToFds();	addProtocolsToFds();	myProtocolsChanged = false;    }    VVERBOSE(log) << fn << ": " << *this << VVERBOSE_END(log);    VDEBUG(log) << fn << ": polling for activity. timeout = " << timeout    	    	<< VDEBUG_END(log);        int numberFdsActive = ::poll(&myFds[0], myFds.size(), timeout);    if ( numberFdsActive < SUCCESS )    {    	int error = errno;    	// If we were interrupted, treat it like a timeout.	//    	if ( error == EINTR )	{	    VDEBUG(log) << fn << ": interrupted." << VDEBUG_END(log);    	    return ( 0 );	}	    	throw Vocal::SystemException(fn + " on poll(): " + strerror(error), 	    	    	    	 __FILE__, __LINE__, error);    }        // Clear interruptor so that numberFdsActive corresponds to    // registered file descriptors only.    //    for (   vector<pollfd>::iterator  it = myFds.begin();    	    it != myFds.end() && numberFdsActive > 0;	    it++	)    {    	pollfd	    &   pollFdEntry = (*it);    	if ( processInterruptor(pollFdEntry) )	{    	    VVERBOSE(log) << fn << ": " << *this << VVERBOSE_END(log);	    numberFdsActive--;	    pollFdEntry.revents = 0;	    break;	}    }            return ( numberFdsActive );}Poll::EventTypePoll::fdActive(const FileDescriptor & filedesc) const{    EventType returnEvent = 0;        file_descriptor_t   fd = filedesc.getFD();        for (   vector<pollfd>::const_iterator i = myFds.begin();            i != myFds.end();            ++i        )    {        if ( fd == i->fd )        {            returnEvent = i->revents;            break;        }    }    return ( returnEvent );}void 	    	    Poll::processProtocols(int numberFdsActive)throw ( Vocal::Transport::ProtocolException ){    const string    fn("Poll::processProtocols");    VLog    	    log(fn);    VDEBUG(log) << fn << ": Start: number file descriptors active = "     	    	<< numberFdsActive 	    	<< ", protocols changed = " 		<< ( myProtocolsChanged ? "true" : "false" )		<< VDEBUG_END(log);    VVERBOSE(log) << fn << ": " << *this << VVERBOSE_END(log);		    for (   vector<pollfd>::iterator  it = myFds.begin();    	    it != myFds.end() && numberFdsActive > 0;	    it++	)    {    	pollfd	    &   pollFdEntry = (*it);    	if ( pollFdEntry.fd == myInterruptor.readFD().getFD() )	{	    pollFdEntry.revents = 0;	    continue;	}    	ProtocolMap::iterator   protocolIt = myProtocols.find(pollFdEntry);		if ( protocolIt == myProtocols.end() )	{	    // If a two protocols are active, but then second protocol	    // is unregistered as a result of activity on the first 	    // protocol, we will end up here.	    //	    myProtocolsChanged = true;	    VDEBUG(log) << fn << ": no protocol found for: fd = "	    	    	<< it->fd << VDEBUG_END(log);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -