• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

spl/net/SocketSet.h

00001 /*
00002  *   This file is part of the Standard Portable Library (SPL).
00003  *
00004  *   SPL is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   SPL is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with SPL.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 #ifndef _socketset_h
00018 #define _socketset_h
00019 
00020 #include <spl/types.h>
00021 #include <spl/Debug.h>
00022 
00023 #ifdef _WINDOWS
00024 #include <spl/configwin32.h>
00025 #else
00026 #include <spl/autoconf/config.h>
00027 #endif
00028 
00029 #include <spl/collection/Array.h>
00030 #include <spl/net/Socket.h>
00031 #include <spl/io/IStream.h>
00032 #include <spl/net/Socket.h>
00033 #include <spl/threading/Event.h>
00034 #include <spl/threading/Mutex.h>
00035 #include <spl/net/PortListener.h>
00036 #include <spl/threading/Thread.h>
00037 #include <spl/collection/Hashtable.h>
00038 
00046 class ISocketService
00047 {
00048 public:
00049         inline ISocketService() {}
00050         virtual ~ISocketService();
00051 
00052         virtual void AddSocket( IStreamReadListenerPtr listener, TcpSocketPtr sp ) = 0;
00053         virtual void Close() = 0;
00054         virtual void CloseAndDelete() = 0;
00055         virtual int SocketCount() const = 0;
00056         inline void Broadcast( const Array<byte>& buf ) { Broadcast(buf, buf.Length()); }
00057         virtual void Broadcast( const Array<byte>& buf, const int len ) = 0;
00058         virtual void Join(int timeoutms) = 0;
00059         virtual void Join() = 0;
00060 
00061 #if defined(DEBUG)
00062         virtual void CheckMem() const = 0;
00063         virtual void ValidateMem() const = 0;
00064 #endif
00065 };
00066 
00067 #ifdef DEBUG
00068 inline void ValidateType( ISocketService *iss )
00069 {
00070         iss->CheckMem();
00071         iss->ValidateMem();
00072 }
00073 inline void ValidateType( const ISocketService& iss )
00074 {
00075         iss.CheckMem();
00076         iss.ValidateMem();
00077 }
00078 #endif
00079 
00080 REGISTER_TYPEOF(52, ISocketService);
00081 
00083 class SocketListenerPair
00084 {
00085 public:
00086         IStreamReadListenerPtr m_listener;
00087         TcpSocketPtr m_sp;
00088 
00089         SocketListenerPair(IStreamReadListenerPtr listener, TcpSocketPtr sp);
00090         
00091         inline ~SocketListenerPair()
00092         {
00093         }
00094 };
00095 
00096 REGISTER_TYPEOF(54, SocketListenerPair);
00097 
00098 #ifdef DEBUG
00099 inline void ValidateType( SocketListenerPair *slp )
00100 {
00101         if ( NULL != slp )
00102         {
00103                 ASSERT_MEM( slp, sizeof(SocketListenerPair) );
00104                 DEBUG_NOTE_MEM( slp );
00105                 slp->m_listener.ValidateMem();
00106                 slp->m_sp.ValidateMem();
00107                 slp->m_listener.CheckMem();
00108                 slp->m_sp.CheckMem();
00109         }
00110 }
00111 #endif
00112 
00113 class SocketSet;
00114 typedef RefCountPtr<SocketSet> SocketSetPtr;
00115 
00116 REGISTER_TYPEOF(56, SocketSetPtr);
00117 
00119 class SocketSet : public ISocketService, public Thread
00120 {
00121 private:
00122         // Copy constructor doesn't make sense for this class
00123         inline SocketSet(const SocketSet& ss) {}
00124         inline void operator =(const SocketSet& s) {}
00125 
00126 protected:
00127         Array<byte> m_buf;
00128         Vector<SocketListenerPair *>m_vread;
00129         struct timeval *m_to;
00130         fd_set m_read;
00131         fd_set m_excpt;
00132 
00133         Event *m_sockAddedEvent;
00134         Mutex m_svreadMutex;
00135         volatile bool m_running;
00136 
00137         void WaitForIO();
00138         void Run();
00139         bool RemoveSocket( TcpSocket& sp );
00140 
00141 public:
00142         SocketSet(  );
00143         virtual ~SocketSet();
00144 
00145         virtual void AddSocket( IStreamReadListenerPtr listener, TcpSocketPtr sp );
00146         virtual void Close();
00147         virtual void CloseAndDelete();
00148         virtual int SocketCount() const;
00149         void Broadcast( const Array<byte>& buf, const int len );
00150 
00151         virtual void Join(int timeoutms);
00152         virtual void Join();
00153 
00154         inline void Lock() { m_svreadMutex.Lock(); }
00155         inline void UnLock() { m_svreadMutex.Unlock(); }
00156 
00157 #if defined(DEBUG) || defined(_DEBUG)
00158         virtual void CheckMem() const;
00159         virtual void ValidateMem() const;
00160 #endif
00161 };
00162 
00163 REGISTER_TYPEOF(58, SocketSet);
00164 
00165 inline void ValidateType( SocketSet *ss )
00166 {
00167         if ( NULL != ss )
00168         {
00169                 ASSERT_MEM( ss, sizeof(SocketSet) );
00170                 DEBUG_NOTE_MEM( ss );
00171         }
00172 }
00173 
00174 class IServerConnectionFactory;
00175 typedef RefCountPtr<IServerConnectionFactory> IServerConnectionFactoryPtr;
00176 
00177 REGISTER_TYPEOF(60, IServerConnectionFactoryPtr);
00178 
00182 class IServerConnectionFactory : public IMemoryValidate
00183 {
00184 public:
00185         virtual ~IServerConnectionFactory();
00186         virtual IStreamReadListenerPtr Create(TcpSocketPtr sock) = 0;
00187 };
00188 
00189 REGISTER_TYPEOF(62, IServerConnectionFactory);
00190 
00191 class SocketSetServer;
00192 typedef RefCountPtr<SocketSetServer> SocketSetServerPtr;
00193 
00194 REGISTER_TYPEOF(64, SocketSetServerPtr);
00195 
00197 class SocketSetServer : public ISocketService, public IPortListenerListener
00198 {
00199 protected:
00200         SocketSet m_ss;
00201         PortListener m_listener;
00202         IServerConnectionFactory *m_conFactory;
00203 
00204         virtual void IPortListener_OnConnect( TcpSocketPtr sock );
00205         virtual void IPortListener_OnStop();
00206 
00207 public:
00208         SocketSetServer(IServerConnectionFactory *conFactory, int serverPort);
00209         virtual ~SocketSetServer();
00210 
00211         virtual void AddSocket( IStreamReadListenerPtr listener, TcpSocketPtr sp );
00212         virtual void Close();
00213         virtual void CloseAndDelete();
00214         virtual int SocketCount() const;
00215         virtual void Broadcast( const Array<byte>& buf, const int len );
00216 
00217         virtual void Join(int timeoutms);
00218         virtual void Join();
00219 
00220 #if defined(DEBUG) || defined(_DEBUG)
00221         virtual void CheckMem() const;
00222         virtual void ValidateMem() const;
00223 #endif
00224 };
00225 
00226 REGISTER_TYPEOF(66, SocketSetServer);
00227 
00230 #endif