/*
* Copyright (C) 2001-2004 Peter J Jones (pjones@pmade.org)
* 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. Neither the name of the Author nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 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.
*/
/** @file
* This file contains the defintion of the Netxx::Probe class.
**/
#ifndef _netxx_probe_h_
#define _netxx_probe_h_
// Netxx includes
#include <netxx/types.h>
#include <netxx/timeout.h>
#include <netxx/probeinfo.h>
// standard includes
#include <vector>
#include <utility>
namespace Netxx {
class PipeCompatibleProbe;
/**
* The Netxx::Probe class is a wrapper around one of the Netxx probe
* classes. The reason that we have a wrapper is because most operating
* systems support select(2) but some also support more advanced APIs like
* kqueue(2) or /dev/poll.
**/
class Probe {
/*
* Probe has no public way to select read only and write only sockets
* needed for probing pipes, so grant PipeCompatibleProbe to use add_socket
*/
friend class PipeCompatibleProbe;
public:
/*
* Bitmask for telling Probe exactly what you want and for testing the
* return value from Probe::ready().
*/
enum ReadyType {
ready_none = 0x000000, ///< Nothing or Everything depeding on the context
ready_read = 0x000001, ///< Readable
ready_write = 0x000002, ///< Writable
ready_oobd = 0x000004 ///< Readable Out-of-band Data
};
/// type for holding the bitmask
typedef unsigned int ready_type;
/// type returned from ready()
typedef std::pair<socket_type, ready_type> result_type;
//####################################################################
/**
* Construct a new Netxx::Probe object.
*
* @author Peter Jones
**/
//####################################################################
Probe (void);
//####################################################################
/**
* Netxx::Probe copy constructor.
*
* @param other The other Probe object to copy from.
* @author Peter Jones
**/
//####################################################################
Probe (const Probe &other);
//####################################################################
/**
* Netxx::Probe assignment operator.
*
* @param other The other Probe object to copy from.
* @return *this.
* @author Peter Jones
**/
//####################################################################
Probe& operator= (const Probe &other);
//####################################################################
/**
* Swap this Probe and another one. Similar to std::swap().
*
* @param other The other Probe to swap with.
* @author Peter Jones
**/
//####################################################################
void swap(Probe &other);
//####################################################################
/**
* Netxx::Probe destructor.
*
* @author Peter Jones
**/
//####################################################################
~Probe (void);
//####################################################################
/**
* Clear the Probe. All objects will be removed from the Probe and it
* will be in a brand-new like state.
*
* @author Peter Jones
**/
//####################################################################
void clear (void);
//####################################################################
/**
* Preform the probe. This function will block until either some data is
* ready or the given timeout expires. You may also supply a bitmask for
* the type of data you want in this probe.
*
* @param timeout How long to wait for data. Can be a NULL timeout to block until probe data is avaliable.
* @param rt A bitmask to control what is returned. ready_none means all data in this context.
* @return a std::pair where first is the ready socket and second is a bitmask to tell you what it is ready for.
* @return a std::pair with first set to -1 to signal a timeout.
* @author Peter Jones
**/
//####################################################################
result_type ready (const Timeout &timeout=Timeout(), ready_type rt=ready_none);
//####################################################################
/**
* Add an object to the Probe. The object must support the
* Netxx::ProbeInfo class. All Netxx classes such as Stream and Datagram
* support the ProbeInfo class.
*
* You can optionally give a bitmask that will tell Probe what type of
* data to probe for. The default is to probe for all data. In this
* case, ready_none means probe for all data.
*
* @param t The object to add to the Probe.
* @param rt A bitmask that tells Probe what to probe for.
* @author Peter Jones
**/
//####################################################################
template <typename T> void add (const T &t, ready_type rt=ready_none)
{
// implemented inline to work around bug in MSVC
const ProbeInfo *pi = t.get_probe_info();
std::vector<socket_type>::const_iterator i=pi->get_sockets().begin(), end=pi->get_sockets().end();
for (; i!=end; ++i) { if (pi->needs_pending_check()) add_socket(pi, *i, rt); else add_socket(*i, rt); }
}
//####################################################################
/**
* Remove the given object from the Probe.
*
* @param t The object to remove from the Probe.
* @author Peter Jones
**/
//####################################################################
template <typename T> void remove (const T &t)
{
// implemented inline to work around bug in MSVC
const ProbeInfo *pi = t.get_probe_info();
std::vector<socket_type>::const_iterator i=pi->get_sockets().begin(), end=pi->get_sockets().end();
for (; i!=end; ++i) remove_socket(*i);
}
private:
void add_socket (socket_type socketfd, ready_type rt);
void add_socket (const ProbeInfo *pi, socket_type socketfd, ready_type rt);
void remove_socket (socket_type socketfd);
struct pimpl; pimpl *pimpl_;
}; // end Netxx::Probe class
} // end Netxx namespace
#endif
syntax highlighted by Code2HTML, v. 0.9.1