00001 #ifndef _STR_SockListenModule_H_ // -*-c++-*-
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef __GNUG__
00022 # pragma interface
00023 #endif
00024
00025
00026
00027
00028
00029
00030
00031 #include <string>
00032
00033 #include <UniEvent/EventPtr.h>
00034 #include <UniEvent/UnixEventRegistry.h>
00035 #include <UniEvent/UNIXError.h>
00036 #include <EHnet++/SocketAddress.h>
00037
00038 #ifndef _STR_StreamModule_H_
00039 # include <StrMod/StreamModule.h>
00040 #endif
00041
00042 #ifndef _STR_StrChunk_H_
00043 # include <StrMod/StrChunk.h>
00044 #endif
00045
00046 #ifndef _STR_StrChunkPtrT_H_
00047 # include <StrMod/StrChunkPtrT.h>
00048 #endif
00049
00050 #ifndef _STR_SocketModule_H_
00051 # include <StrMod/SocketModule.h>
00052 #endif
00053
00054
00055 #define _STR_SockListenModule_H_
00056
00057 namespace strmod {
00058 namespace strmod {
00059
00060 class ListeningPlug;
00061 class SocketModuleChunk;
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 class SocketModuleChunk : public StrChunk
00075 {
00076 public:
00077 static const STR_ClassIdent identifier;
00078
00079
00080 explicit SocketModuleChunk(SocketModule *mod) : module_(mod) { }
00081
00082 inline virtual ~SocketModuleChunk();
00083
00084 inline virtual int AreYouA(const lcore::ClassIdent &cid) const;
00085
00086 virtual unsigned int Length() const { return 0; }
00087
00088
00089
00090
00091
00092
00093 SocketModule *getModule(bool release = true)
00094 {
00095 SocketModule *ret = module_;
00096 if (release)
00097 {
00098 module_ = 0;
00099 }
00100 return ret;
00101 }
00102
00103 protected:
00104 virtual const lcore::ClassIdent *i_GetIdent() const { return &identifier; }
00105
00106
00107 virtual void acceptVisitor(ChunkVisitor &visitor)
00108 throw(ChunkVisitor::halt_visitation) { }
00109
00110 private:
00111 SocketModule *module_;
00112 };
00113
00114 typedef StrChunkPtrT<SocketModuleChunk> SocketModuleChunkPtr;
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 class SockListenModule : public StreamModule {
00125 class FDPollEv;
00126 friend class FDPollEv;
00127 class FDPollRdEv;
00128 friend class FDPollRdEv;
00129 class FDPollErEv;
00130 friend class FDPollErEv;
00131
00132 public:
00133 class SLPlug;
00134 friend class SLPlug;
00135 static const STR_ClassIdent identifier;
00136
00137
00138
00139
00140 SockListenModule(const ehnet::SocketAddress &bind_addr,
00141 unievent::Dispatcher &disp,
00142 unievent::UnixEventRegistry &ureg,
00143 int qlen = 1);
00144
00145 virtual ~SockListenModule();
00146
00147 inline virtual int AreYouA(const lcore::ClassIdent &cid) const;
00148
00149 inline virtual bool canCreate(int side = 0) const;
00150 inline SLPlug *makePlug(int side = 0);
00151 inline virtual bool ownsPlug(const Plug *plug) const;
00152 inline virtual bool deletePlug(Plug *plug);
00153
00154
00155 bool hasError() const throw() { return has_error_; }
00156
00157 const unievent::UNIXError &getError() const throw();
00158
00159 void clearError() throw();
00160
00161
00162 const ehnet::SocketAddress &GetBoundAddress() const { return(myaddr_); }
00163
00164
00165
00166
00167 class SLPlug : public StreamModule::Plug {
00168 friend class SockListenModule;
00169
00170 public:
00171 static const STR_ClassIdent identifier;
00172
00173 inline virtual int AreYouA(const lcore::ClassIdent &cid) const;
00174
00175 inline SockListenModule &getParent() const;
00176 virtual int side() const { return(0); }
00177
00178
00179 const SocketModuleChunkPtr getConnection();
00180
00181 protected:
00182
00183 SLPlug(SockListenModule &parent) : Plug(parent) { }
00184
00185
00186 virtual ~SLPlug() { }
00187
00188 virtual const lcore::ClassIdent *i_GetIdent() const {
00189 return &identifier;
00190 }
00191
00192
00193 virtual const StrChunkPtr i_Read();
00194
00195
00196 virtual void i_Write(const StrChunkPtr &ptr);
00197 };
00198
00199 protected:
00200 virtual const lcore::ClassIdent *i_GetIdent() const { return &identifier; }
00201
00202 inline virtual Plug *i_MakePlug(int side);
00203
00204
00205
00206
00207 inline SocketModule *makeSocketModule(int fd, ehnet::SocketAddress *peer,
00208 unievent::Dispatcher &disp,
00209 unievent::UnixEventRegistry &ureg);
00210
00211
00212 inline void setError(const unievent::UNIXError &err) throw();
00213
00214
00215 SocketModule *getNewModule();
00216
00217 private:
00218 typedef unievent::Dispatcher Dispatcher;
00219 typedef unievent::UnixEventRegistry UnixEventRegistry;
00220
00221 int sockfd_;
00222 unsigned char errorstore_[sizeof(unievent::UNIXError)];
00223 bool has_error_;
00224 SLPlug lplug_;
00225 bool plug_pulled_;
00226 bool checking_read_;
00227 SocketModule *newmodule_;
00228 ehnet::SocketAddress &myaddr_;
00229 Dispatcher &disp_;
00230 UnixEventRegistry &ureg_;
00231 FDPollEv *readevptr_;
00232 unievent::EventPtr readev_;
00233 FDPollEv *errorevptr_;
00234 unievent::EventPtr errorev_;
00235
00236 void eventRead();
00237 void eventError();
00238 void doAccept();
00239 };
00240
00241
00242
00243 inline SocketModuleChunk::~SocketModuleChunk()
00244 {
00245 if (module_)
00246 {
00247 delete module_;
00248 }
00249 }
00250
00251 inline int SocketModuleChunk::AreYouA(const lcore::ClassIdent &cid) const
00252 {
00253 return((identifier == cid) || StrChunk::AreYouA(cid));
00254 }
00255
00256
00257
00258 inline int SockListenModule::AreYouA(const lcore::ClassIdent &cid) const
00259 {
00260 return((identifier == cid) || StreamModule::AreYouA(cid));
00261 }
00262
00263 inline bool SockListenModule::canCreate(int side) const
00264 {
00265 return((side == 0) && !plug_pulled_ && !hasError());
00266 }
00267
00268 inline SockListenModule::SLPlug *SockListenModule::makePlug(int side)
00269 {
00270 return((SLPlug *)(i_MakePlug(side)));
00271 }
00272
00273 inline bool SockListenModule::ownsPlug(const Plug *plug) const
00274 {
00275 return(plug_pulled_ && (plug == &lplug_));
00276 }
00277
00278 inline bool SockListenModule::deletePlug(Plug *plug)
00279 {
00280 if (ownsPlug(plug))
00281 {
00282 lplug_.unPlug();
00283 plug_pulled_ = false;
00284 return(true);
00285 }
00286 else
00287 {
00288 return(false);
00289 }
00290 }
00291
00292 inline StreamModule::Plug *SockListenModule::i_MakePlug(int side)
00293 {
00294 if (side != 0 || plug_pulled_ || hasError())
00295 {
00296 return(0);
00297 } else {
00298 plug_pulled_ = true;
00299 return(&lplug_);
00300 }
00301 }
00302
00303 inline SocketModule *
00304 SockListenModule::makeSocketModule(int fd, ehnet::SocketAddress *peer,
00305 unievent::Dispatcher &disp,
00306 unievent::UnixEventRegistry &ureg)
00307 {
00308
00309 return(new SocketModule(fd, peer, disp, ureg));
00310 }
00311
00312
00313
00314 inline int SockListenModule::SLPlug::AreYouA(const lcore::ClassIdent &cid) const
00315 {
00316 return((identifier == cid) || Plug::AreYouA(cid));
00317 }
00318
00319 inline SockListenModule &SockListenModule::SLPlug::getParent() const
00320 {
00321 return(static_cast<SockListenModule &>(Plug::getParent()));
00322 }
00323
00324 };
00325 };
00326
00327 #endif