XrdSysIOEvents.hh

Go to the documentation of this file.
00001 #ifndef __XRDSYSIOEVENTS_HH__
00002 #define __XRDSYSIOEVENTS_HH__
00003 /******************************************************************************/
00004 /*                                                                            */
00005 /*                     X r d S y s I O E v e n t s . h h                      */
00006 /*                                                                            */
00007 /* (c) 2012 by the Board of Trustees of the Leland Stanford, Jr., University  */
00008 /*                            All Rights Reserved                             */
00009 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00010 /*              DE-AC02-76-SFO0515 with the Department of Energy              */
00011 /*                                                                            */
00012 /* This file is part of the XRootD software suite.                            */
00013 /*                                                                            */
00014 /* XRootD is free software: you can redistribute it and/or modify it under    */
00015 /* the terms of the GNU Lesser General Public License as published by the     */
00016 /* Free Software Foundation, either version 3 of the License, or (at your     */
00017 /* option) any later version.                                                 */
00018 /*                                                                            */
00019 /* XRootD is distributed in the hope that it will be useful, but WITHOUT      */
00020 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or      */
00021 /* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public       */
00022 /* License for more details.                                                  */
00023 /*                                                                            */
00024 /* You should have received a copy of the GNU Lesser General Public License   */
00025 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file  */
00026 /* COPYING (GPL license).  If not, see <http://www.gnu.org/licenses/>.        */
00027 /*                                                                            */
00028 /* The copyright holder's institutional names and contributor's names may not */
00029 /* be used to endorse or promote products derived from this software without  */
00030 /* specific prior written permission of the institution or contributor.       */
00031 /******************************************************************************/
00032   
00033 #include <poll.h>
00034 #include <time.h>
00035 #include <sys/types.h>
00036 
00037 #include "XrdSys/XrdSysPthread.hh"
00038 
00039 //-----------------------------------------------------------------------------
00053 //-----------------------------------------------------------------------------
00054 
00055 namespace XrdSys
00056 {
00057 namespace IOEvents
00058 {
00059 
00060 /******************************************************************************/
00061 /*                        C l a s s   C a l l B a c k                         */
00062 /******************************************************************************/
00063 
00064 //-----------------------------------------------------------------------------
00074 //-----------------------------------------------------------------------------
00075   
00076 class Channel;
00077 class CallBack
00078 {
00079 public:
00080 
00081 //-----------------------------------------------------------------------------
00083 //-----------------------------------------------------------------------------
00084 
00085       enum EventType
00086       {
00087         ReadyToRead  = 0x01,  
00088         ReadTimeOut  = 0x02,  
00089         ReadyToWrite = 0x04,  
00090         WriteTimeOut = 0x08   
00091       };
00092 
00093 //-----------------------------------------------------------------------------
00110 //-----------------------------------------------------------------------------
00111 
00112 virtual bool Event(Channel *chP, void *cbArg, int evFlags) = 0;
00113 
00114 //-----------------------------------------------------------------------------
00125 //-----------------------------------------------------------------------------
00126 
00127 virtual void Fatal(Channel *chP, void *cbArg, int eNum, const char *eTxt)
00128 {
00129   (void)chP; (void)cbArg; (void)eNum; (void)eTxt;
00130 };
00131 
00132 //-----------------------------------------------------------------------------
00140 //-----------------------------------------------------------------------------
00141 
00142 virtual void Stop(Channel *chP, void *cbArg)
00143 {
00144   (void)chP; (void)cbArg;
00145 }
00146 
00147 //-----------------------------------------------------------------------------
00149 //-----------------------------------------------------------------------------
00150 
00151             CallBack() {}
00152 
00153 //-----------------------------------------------------------------------------
00155 //-----------------------------------------------------------------------------
00156 
00157 virtual    ~CallBack() {}
00158 };
00159 
00160 /******************************************************************************/
00161 /*                         C l a s s   C h a n n e l                          */
00162 /******************************************************************************/
00163 
00164 //-----------------------------------------------------------------------------
00168 //-----------------------------------------------------------------------------
00169   
00170 class ChannelWait;
00171 class Poller;
00172 class Channel
00173 {
00174 friend class Poller;
00175 public:
00176 
00177 //-----------------------------------------------------------------------------
00179 //-----------------------------------------------------------------------------
00180 
00181 enum EventCode {readEvents  = 0x01, 
00182                 writeEvents = 0x04, 
00183                 rwEvents    = 0x05, 
00184                 errorEvents = 0x10, 
00185                 stopEvent   = 0x20, 
00186                 allEvents   = 0x35  
00187                };
00188 
00189 //-----------------------------------------------------------------------------
00199 //-----------------------------------------------------------------------------
00200 
00201         bool Disable(int events, const char **eText=0);
00202 
00203 //-----------------------------------------------------------------------------
00235 //-----------------------------------------------------------------------------
00236 
00237         bool Enable(int events, int timeout=0, const char **eText=0);
00238 
00239 //-----------------------------------------------------------------------------
00244 //-----------------------------------------------------------------------------
00245 
00246         void GetCallBack(CallBack **cbP, void **cbArg);
00247 
00248 //-----------------------------------------------------------------------------
00254 //-----------------------------------------------------------------------------
00255 
00256         int  GetEvents() {return (chPoller ? static_cast<int>(chEvents) : -1);}
00257 
00258 //-----------------------------------------------------------------------------
00263 //-----------------------------------------------------------------------------
00264 
00265         int  GetFD() {return chFD;}
00266 
00267 //-----------------------------------------------------------------------------
00274 //-----------------------------------------------------------------------------
00275 
00276         void SetCallBack(CallBack *cbP, void *cbArg=0);
00277 
00278 //-----------------------------------------------------------------------------
00287 //-----------------------------------------------------------------------------
00288 
00289         void SetFD(int fd);
00290 
00291 //-----------------------------------------------------------------------------
00306 //-----------------------------------------------------------------------------
00307 
00308       Channel(Poller *pollP, int fd, CallBack *cbP=0, void *cbArg=0);
00309 
00310 //-----------------------------------------------------------------------------
00314 //-----------------------------------------------------------------------------
00315 
00316      ~Channel();
00317 
00318 private:
00319 
00320 struct dlQ {Channel *next; Channel *prev;};
00321 
00322 XrdSysRecMutex chMutex;
00323 
00324 dlQ            attList;     // List of attached channels
00325 dlQ            tmoList;     // List of channels in the timeout queue
00326 
00327 Poller        *chPoller;    // The effective poller
00328 Poller        *chPollXQ;    // The real      poller
00329 CallBack      *chCB;        // CallBack function
00330 void          *chCBA;       // CallBack argument
00331 int            chFD;        // Associated file descriptor
00332 int            pollEnt;     // Used only for poll() type pollers
00333 int            chRTO;       // Read  timeout value (0 means none)
00334 int            chWTO;       // Write timeout value (0 means none)
00335 time_t         rdDL;        // Read  deadline
00336 time_t         wrDL;        // Write deadline
00337 time_t         deadLine;    // The deadline in effect (read or write)
00338 char           dlType;      // The deadline type in deadLine as CallBack type
00339 char           chEvents;    // Enabled events as Channel type
00340 char           chStat;      // Channel status below (!0 -> in callback mode)
00341 enum Status   {isClear = 0, isCBMode, isDead};
00342 char           inTOQ;       // True if the channel is in the timeout queue
00343 char           inPSet;      // FD is in the actual poll set
00344 char           reMod;       // Modify issued while defered, re-issue needed
00345 short          chFault;     // Defered error, 0 if all is well
00346 
00347 void           Reset(Poller *thePoller, int fd, int eNum=0);
00348 };
00349 
00350 /******************************************************************************/
00351 /*                          C l a s s   P o l l e r                           */
00352 /******************************************************************************/
00353   
00354 //-----------------------------------------------------------------------------
00360 //-----------------------------------------------------------------------------
00361 
00362 class Poller
00363 {
00364 friend class BootStrap;
00365 friend class Channel;
00366 public:
00367 
00368 //-----------------------------------------------------------------------------
00382 //-----------------------------------------------------------------------------
00383 
00384 static Poller     *Create(int &eNum, const char **eTxt=0);
00385 
00386 //-----------------------------------------------------------------------------
00397 //-----------------------------------------------------------------------------
00398 
00399        void        Stop();
00400 
00401 //-----------------------------------------------------------------------------
00406 //-----------------------------------------------------------------------------
00407 
00408          Poller(int cFD, int rFD);
00409 
00410 //-----------------------------------------------------------------------------
00412 //-----------------------------------------------------------------------------
00413 
00414 virtual ~Poller() {}
00415 
00416 protected:
00417 struct  PipeData;
00418 
00419         void  CbkTMO();
00420         bool  CbkXeq(Channel *cP, int events, int eNum, const char *eTxt);
00421 inline  int   GetFault(Channel *cP)   {return cP->chFault;}
00422 inline  int   GetPollEnt(Channel *cP) {return cP->pollEnt;}
00423         int   GetRequest();
00424         bool  Init(Channel *cP, int &eNum, const char **eTxt, bool &isLockd);
00425 inline  void  LockChannel(Channel *cP) {cP->chMutex.Lock();}
00426         int   Poll2Enum(short events);
00427         int   SendCmd(PipeData &cmd);
00428         void  SetPollEnt(Channel *cP, int ptEnt);
00429         bool  TmoAdd(Channel *cP);
00430         void  TmoDel(Channel *cP);
00431         int   TmoGet();
00432 inline  void  UnLockChannel(Channel *cP) {cP->chMutex.UnLock();}
00433 
00437 virtual void Begin(XrdSysSemaphore *syncp, int &rc, const char **eTxt) = 0;
00438 
00443 virtual void Exclude(Channel *cP, bool &isLocked, bool dover=1) = 0;
00444 
00449 virtual bool Include(Channel     *cP,
00450                      int         &eNum,
00451                      const char **eTxt,
00452                      bool        &isLocked) = 0;
00453 
00458 virtual bool Modify (Channel     *cP,
00459                      int         &eNum,
00460                      const char **eTxt,
00461                      bool        &isLocked) = 0;
00462 
00467 //
00468 virtual void Shutdown() = 0;
00469 
00470 // The following is common to all implementations
00471 //
00472 Channel        *attBase;    // -> First channel in attach  queue or 0
00473 Channel        *tmoBase;    // -> First channel in timeout queue or 0
00474 
00475 pthread_t       pollTid;    // Poller's thread ID
00476 
00477 struct pollfd   pipePoll;   // Stucture to wait for pipe events
00478 int             cmdFD;      // FD to send PipeData commands
00479 int             reqFD;      // FD to recv PipeData requests
00480 struct          PipeData {char req; char evt; short ent; int fd;
00481                           XrdSysSemaphore *theSem;
00482                           enum cmd {NoOp = 0, MdFD = 1, Post = 2,
00483                                     MiFD = 3, RmFD = 4, Stop = 5};
00484                          };
00485 PipeData        reqBuff;    // Buffer used by poller thread to recv data
00486 char           *pipeBuff;   // Read resumption point in buffer
00487 int             pipeBlen;   // Number of outstanding bytes
00488 bool            wakePend;   // Wakeup is effectively pending (don't send)
00489 bool            chDead;     // True if channel deleted by callback
00490 
00491 static time_t   maxTime;    // Maximum time allowed
00492 
00493 private:
00494 
00495 void Attach(Channel *cP);
00496 void Detach(Channel *cP, bool &isLocked, bool keep=true);
00497 void WakeUp();
00498 
00499 // newPoller() called to get a specialized new poll object at in response to
00500 //             Create(). A specialized implementation must be supplied.
00501 //
00502 static Poller *newPoller(int pFD[2], int &eNum, const char **eTxt);
00503 
00504 XrdSysMutex    adMutex; // Mutex for adding & detaching channels
00505 XrdSysMutex    toMutex; // Mutex for handling the timeout list
00506 };
00507 };
00508 };
00509 #endif

Generated on 16 Jan 2014 for xrootd by  doxygen 1.4.7