00001
00002
00003
00004
00005 #ifndef EQNET_CONNECTION_SET_H
00006 #define EQNET_CONNECTION_SET_H
00007
00008 #include <eq/net/connectionListener.h>
00009 #include <eq/net/pipeConnection.h>
00010
00011 #include <eq/base/base.h>
00012 #include <eq/base/buffer.h>
00013 #include <eq/base/hash.h>
00014 #include <eq/base/refPtr.h>
00015
00016 #ifndef WIN32
00017 # include <poll.h>
00018 #endif
00019
00020 namespace eq
00021 {
00022 namespace net
00023 {
00024 class Message;
00025 class Network;
00026 class PipeConnection;
00027
00033 class EQ_EXPORT ConnectionSet : public ConnectionListener
00034 {
00035 public:
00036 enum Event
00037 {
00038 EVENT_NONE = 0,
00039 EVENT_CONNECT,
00040 EVENT_DISCONNECT,
00041 EVENT_DATA,
00042 EVENT_TIMEOUT,
00043 EVENT_INTERRUPT,
00044 EVENT_ERROR,
00045 EVENT_SELECT_ERROR,
00046 EVENT_INVALID_HANDLE,
00047 EVENT_ALL
00048 };
00049
00050 ConnectionSet();
00051 ~ConnectionSet();
00052
00053 void addConnection( ConnectionPtr connection );
00054 bool removeConnection( ConnectionPtr connection );
00055 void clear();
00056 size_t size() const { return _connections.size(); }
00057 bool empty() const { return _connections.empty(); }
00058
00059 const ConnectionVector& getConnections() const { return _connections; }
00060
00071 Event select( const int timeout = -1 );
00072
00076 void interrupt();
00077
00078 int getError() { return _error; }
00079 ConnectionPtr getConnection(){ return _connection; }
00080
00081 private:
00083 base::SpinLock _mutex;
00084
00086 ConnectionVector _connections;
00087
00088
00089 #ifdef WIN32
00090 base::Buffer< HANDLE > _fdSet;
00091 #else
00092 base::Buffer< pollfd > _fdSetCopy;
00093 base::Buffer< pollfd > _fdSet;
00094 #endif
00095 base::Buffer< Connection* > _fdSetConnections;
00096
00097 enum SelfCommands
00098 {
00099 SELF_INTERRUPT = 42
00100 };
00101
00103 base::RefPtr< PipeConnection > _selfConnection;
00104
00105
00106 ConnectionPtr _connection;
00107 int _error;
00108
00110 bool _dirty;
00111
00112 bool _getEvent( Event& event, Connection::ReadNotifier& fd );
00113 void _dirtyFDSet();
00114 bool _setupFDSet();
00115 bool _buildFDSet();
00116 virtual void notifyStateChanged( Connection* ) { _dirty = true; }
00117
00118 Event _handleSelfCommand();
00119 Event _getSelectResult( const uint32_t index );
00120 };
00121
00122 EQ_EXPORT std::ostream& operator << ( std::ostream& os,
00123 const ConnectionSet* set );
00124 EQ_EXPORT std::ostream& operator << ( std::ostream& os,
00125 const ConnectionSet::Event event );
00126 }
00127 }
00128
00129 #endif // EQNET_CONNECTION_SET_H