demux_posix_demuxer.hpp

00001 #line 3 "./lpsrc/flx_posix_demux.ipk"
00002 #ifndef __FLX_DEMUX_POSIX_DEMUXER_H__
00003 #define __FLX_DEMUX_POSIX_DEMUXER_H__
00004 
00005 // base classes for posix style demuxers
00006 
00007 #include "demux_demuxer.hpp"
00008 
00009 namespace flx { namespace demux {
00010 class DEMUX_EXTERN posix_demuxer;            // fwd decl
00011 
00012 // abc
00013 class DEMUX_EXTERN posix_wakeup {
00014 public:
00015   virtual ~posix_wakeup() {}
00016 
00017   // when called, the wakeup has finished and been removed.
00018   virtual void wakeup(posix_demuxer& demux) = 0;
00019 };
00020 
00021 class DEMUX_EXTERN socket_wakeup : public posix_wakeup {
00022 public:
00023   int   s;                // the non blocking socket
00024   int   wakeup_flags;         // set on wakeup, r/w or both
00025 
00026   socket_wakeup() : s(-1) {}
00027 };
00028 
00029 class DEMUX_EXTERN posix_demuxer : public demuxer {
00030 protected:
00031   void async_quit(); // useful for requesting wait thread quit in
00032                      // thread safe demuxer destructors. doesn't throw.
00033 
00034 public:
00035   virtual ~posix_demuxer();
00036 
00037   // posix style sockets. for reading and writing (but not both at once
00038   // for the same socket_wakeup) you are guaranteed to receive only one
00039   // wakeup per call to this function when you call wait.
00040   // returns -1 if no wakeup is coming and zero if one is.
00041   // For simultaneous reading and writing you may get two wakeups,
00042   // that is, it may violate the "one shot" rule. Ignoring for now,
00043   // as it's not a common use. This makes it undefined behaviour.
00044   // wakeup is owned by the demuxer until its wakeup is called,
00045   // so treat it with kid gloves, i.e. don't mess with it.
00046   virtual int   add_socket_wakeup(socket_wakeup* sv, int flags) = 0;
00047 
00048   // to be called when we can read & write without blocking
00049   // return true if connection closed, update pb
00050   // sort of a strange place to have this..., more a socket wakeup
00051   // thing, even if static
00052   static bool   socket_recv(int s, sel_param* pb);
00053   static bool   socket_send(int s, sel_param* pb);
00054 };
00055 
00056 // some handy control blocks for common non-blocking socket operations
00057 // note that they "fortuitously" both have start methods. hmm.
00058 // a socket io one could be handy here.
00059 
00060 // this one's restartable (makes sense for listener sockets)
00061 class DEMUX_EXTERN accept_control_block : public socket_wakeup {
00062 public:
00063   int   accepted;   // accepted socket (out)
00064   int   socket_err;   // the error, if acceptee == -1, else 0 (out)
00065 
00066   accept_control_block() : accepted(-1), socket_err(0) {}
00067 
00068   virtual int start(posix_demuxer& demux);
00069   virtual void wakeup(posix_demuxer& demux);
00070 };
00071 
00072 class DEMUX_EXTERN connect_control_block : public socket_wakeup {
00073 public:
00074   int     socket_err;   // outgoing error (on start or wake)
00075   // this should probably be a sockaddr type
00076   const char* addy;     // addr (dotted quad) (in)
00077   int     p;        // port (in)
00078 
00079   connect_control_block() : socket_err(0) {}
00080 
00081   virtual int start(posix_demuxer& demux);
00082   virtual void wakeup(posix_demuxer& demux);
00083 
00084   // oops, can't check for s != -1 as it's always there.
00085   // was always "finished" and so I started io, losing the first wakeup
00086   // on epoll evtsrc. Is this right, or should it be != EINPROGRESS?
00087   // keep in sync with iocp version. give socket_err initial definition
00088   // that works with this?
00089   bool finished() { return ( 0 == socket_err); }
00090 };
00091 
00092 }} // namespace demux, flx
00093 #endif
00094 

Generated on Mon Dec 24 04:04:21 2007 for Felix by  doxygen 1.5.4