emailrelay/src/gnet/geventhandler.cpp
Graeme Walker def9081f44 v1.2
2003-11-06 12:00:00 +00:00

174 lines
3.9 KiB
C++

//
// Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ===
//
// geventhandler.cpp
//
#include "gdef.h"
#include "gnet.h"
#include "geventhandler.h"
#include "geventloop.h"
#include "gdebug.h"
#include "gassert.h"
#include "gdescriptor.h"
#include "glog.h"
#include <algorithm> // std::find
namespace
{
struct Eq
{
GNet::Descriptor m_fd ;
explicit Eq( GNet::Descriptor fd ) : m_fd(fd) {}
bool operator()( const GNet::EventHandlerListItem & item ) const
{
return item.m_fd == m_fd ;
}
} ;
struct NotNull
{
GNet::Descriptor m_fd ;
explicit NotNull( GNet::Descriptor fd ) : m_fd(fd) {}
bool operator()( const GNet::EventHandlerListItem & item ) const
{
return item.m_fd == m_fd && item.m_handler != NULL ;
}
} ;
}
GNet::EventHandlerListItem::EventHandlerListItem( Descriptor fd , EventHandler * handler ) :
m_fd(fd) ,
m_handler(handler)
{
}
bool operator!=( const GNet::EventHandlerListItem & a , const GNet::EventHandlerListItem & b )
{
return a.m_fd != b.m_fd ;
}
// ===
GNet::EventHandler::~EventHandler()
{
}
void GNet::EventHandler::readEvent()
{
G_DEBUG( "GNet::EventHandler::readEvent: no override" ) ;
}
void GNet::EventHandler::writeEvent()
{
G_DEBUG( "GNet::EventHandler::writeEvent: no override" ) ;
}
void GNet::EventHandler::exceptionEvent()
{
G_DEBUG( "GNet::EventHandler::exceptionEvent: no override" ) ;
}
// ===
GNet::EventHandlerList::EventHandlerList( const std::string & type ) :
m_type(type) ,
m_lock(0U)
{
}
GNet::EventHandlerList::Iterator GNet::EventHandlerList::begin() const
{
return m_list.begin() ;
}
GNet::EventHandlerList::Iterator GNet::EventHandlerList::end() const
{
return m_list.end() ;
}
bool GNet::EventHandlerList::contains( Descriptor fd ) const
{
const List::const_iterator end = m_list.end() ;
return std::find_if( m_list.begin() , end , NotNull(fd) ) != end ;
}
GNet::EventHandler * GNet::EventHandlerList::find( Descriptor fd )
{
const List::iterator end = m_list.end() ;
List::iterator p = std::find_if( m_list.begin() , end , NotNull(fd) ) ;
return p != end ? (*p).m_handler : NULL ;
}
void GNet::EventHandlerList::add( Descriptor fd , EventHandler * handler )
{
G_ASSERT( handler != NULL ) ;
G_DEBUG( "GNet::EventHandlerList::add: " << m_type << "-list: " << "adding " << fd ) ;
const List::iterator end = m_list.end() ;
List::iterator p = std::find_if( m_list.begin() , end , Eq(fd) ) ;
if( p != end )
{
G_ASSERT( (*p).m_handler == NULL ) ;
(*p).m_handler = handler ;
}
else
{
m_list.push_back( EventHandlerListItem(fd,handler) ) ;
}
}
void GNet::EventHandlerList::remove( Descriptor fd )
{
G_DEBUG( "GNet::EventHandlerList::remove: " << m_type << "-list: " << "removing " << fd ) ;
const List::iterator end = m_list.end() ;
List::iterator p = std::find_if( m_list.begin() , end , Eq(fd) ) ;
if( p != end )
{
if( m_lock )
(*p).m_handler = NULL ;
else
m_list.erase( p ) ;
}
}
void GNet::EventHandlerList::lock()
{
m_lock++ ;
}
void GNet::EventHandlerList::unlock()
{
m_lock-- ;
if( m_lock == 0U )
{
// collect garbage
const List::iterator end = m_list.end() ;
for( List::iterator p = m_list.begin() ; p != end ; )
{
if( (*p).m_handler == NULL )
p = m_list.erase( p ) ;
else
++p ;
}
}
}