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 #include "XrdSys/XrdSysAtomics.hh"
00039 
00040 //-----------------------------------------------------------------------------
00054 //-----------------------------------------------------------------------------
00055 
00056 namespace XrdSys
00057 {
00058 namespace IOEvents
00059 {
00060 
00061 /******************************************************************************/
00062 /*                        C l a s s   C a l l B a c k                         */
00063 /******************************************************************************/
00064 
00065 //-----------------------------------------------------------------------------
00075 //-----------------------------------------------------------------------------
00076   
00077 class Channel;
00078 class CallBack
00079 {
00080 public:
00081 
00082 //-----------------------------------------------------------------------------
00084 //-----------------------------------------------------------------------------
00085 
00086       enum EventType
00087       {
00088         ReadyToRead  = 0x01,  
00089         ReadTimeOut  = 0x02,  
00090         ReadyToWrite = 0x04,  
00091         WriteTimeOut = 0x08,  
00092         ValidEvents  = 0x0f   
00093       };
00094 
00095 //-----------------------------------------------------------------------------
00114 //-----------------------------------------------------------------------------
00115 
00116 virtual bool Event(Channel *chP, void *cbArg, int evFlags) = 0;
00117 
00118 //-----------------------------------------------------------------------------
00129 //-----------------------------------------------------------------------------
00130 
00131 virtual void Fatal(Channel *chP, void *cbArg, int eNum, const char *eTxt)
00132 {
00133   (void)chP; (void)cbArg; (void)eNum; (void)eTxt;
00134 };
00135 
00136 //-----------------------------------------------------------------------------
00144 //-----------------------------------------------------------------------------
00145 
00146 virtual void Stop(Channel *chP, void *cbArg) { (void)chP; (void)cbArg;}
00147 
00148 //-----------------------------------------------------------------------------
00150 //-----------------------------------------------------------------------------
00151 
00152             CallBack() {}
00153 
00154 //-----------------------------------------------------------------------------
00156 //-----------------------------------------------------------------------------
00157 
00158 virtual    ~CallBack() {}
00159 };
00160 
00161 /******************************************************************************/
00162 /*                         C l a s s   C h a n n e l                          */
00163 /******************************************************************************/
00164 
00165 //-----------------------------------------------------------------------------
00169 //-----------------------------------------------------------------------------
00170   
00171 class ChannelWait;
00172 class Poller;
00173 class Channel
00174 {
00175 friend class Poller;
00176 public:
00177 
00178 //-----------------------------------------------------------------------------
00184 //-----------------------------------------------------------------------------
00185 
00186         void Delete();
00187 
00188 //-----------------------------------------------------------------------------
00190 //-----------------------------------------------------------------------------
00191 
00192 enum EventCode {readEvents  = 0x01, 
00193                 writeEvents = 0x04, 
00194                 rwEvents    = 0x05, 
00195                 errorEvents = 0x10, 
00196                 stopEvent   = 0x20, 
00197                 allEvents   = 0x35  
00198                };
00199 
00200 //-----------------------------------------------------------------------------
00210 //-----------------------------------------------------------------------------
00211 
00212         bool Disable(int events, const char **eText=0);
00213 
00214 //-----------------------------------------------------------------------------
00246 //-----------------------------------------------------------------------------
00247 
00248         bool Enable(int events, int timeout=0, const char **eText=0);
00249 
00250 //-----------------------------------------------------------------------------
00255 //-----------------------------------------------------------------------------
00256 
00257         void GetCallBack(CallBack **cbP, void **cbArg);
00258 
00259 //-----------------------------------------------------------------------------
00265 //-----------------------------------------------------------------------------
00266 
00267 inline  int  GetEvents() {return (chPoller ? static_cast<int>(chEvents) : -1);}
00268 
00269 //-----------------------------------------------------------------------------
00274 //-----------------------------------------------------------------------------
00275 
00276 inline  int  GetFD() {return chFD;}
00277 
00278 //-----------------------------------------------------------------------------
00285 //-----------------------------------------------------------------------------
00286 
00287         void SetCallBack(CallBack *cbP, void *cbArg=0);
00288 
00289 //-----------------------------------------------------------------------------
00298 //-----------------------------------------------------------------------------
00299 
00300         void SetFD(int fd);
00301 
00302 //-----------------------------------------------------------------------------
00317 //-----------------------------------------------------------------------------
00318 
00319       Channel(Poller *pollP, int fd, CallBack *cbP=0, void *cbArg=0);
00320 
00321 private:
00322 
00323 //-----------------------------------------------------------------------------
00325 //-----------------------------------------------------------------------------
00326 
00327      ~Channel() {}
00328 
00329 struct dlQ {Channel *next; Channel *prev;};
00330 
00331 XrdSysRecMutex chMutex;
00332 
00333 dlQ            attList;     // List of attached channels
00334 dlQ            tmoList;     // List of channels in the timeout queue
00335 
00336 Poller        *chPoller;    // The effective poller
00337 Poller        *chPollXQ;    // The real      poller
00338 CallBack      *chCB;        // CallBack function
00339 void          *chCBA;       // CallBack argument
00340 int            chFD;        // Associated file descriptor
00341 int            pollEnt;     // Used only for poll() type pollers
00342 int            chRTO;       // Read  timeout value (0 means none)
00343 int            chWTO;       // Write timeout value (0 means none)
00344 time_t         rdDL;        // Read  deadline
00345 time_t         wrDL;        // Write deadline
00346 time_t         deadLine;    // The deadline in effect (read or write)
00347 char           dlType;      // The deadline type in deadLine as CallBack type
00348 char           chEvents;    // Enabled events as Channel type
00349 char           chStat;      // Channel status below (!0 -> in callback mode)
00350 enum Status   {isClear = 0, isCBMode, isDead};
00351 char           inTOQ;       // True if the channel is in the timeout queue
00352 char           inPSet;      // FD is in the actual poll set
00353 char           reMod;       // Modify issued while defered, re-issue needed
00354 short          chFault;     // Defered error, 0 if all is well
00355 
00356 void           Reset(Poller *thePoller, int fd, int eNum=0);
00357 };
00358 
00359 /******************************************************************************/
00360 /*                          C l a s s   P o l l e r                           */
00361 /******************************************************************************/
00362   
00363 //-----------------------------------------------------------------------------
00369 //-----------------------------------------------------------------------------
00370 
00371 class Poller
00372 {
00373 friend class BootStrap;
00374 friend class Channel;
00375 public:
00376 
00377 //-----------------------------------------------------------------------------
00396 //-----------------------------------------------------------------------------
00397 
00398 enum   CreateOpts  {optTOM};
00399 
00400 static Poller     *Create(int &eNum, const char **eTxt=0, int crOpts=0);
00401 
00402 //-----------------------------------------------------------------------------
00413 //-----------------------------------------------------------------------------
00414 
00415        void        Stop();
00416 
00417 //-----------------------------------------------------------------------------
00422 //-----------------------------------------------------------------------------
00423 
00424          Poller(int cFD, int rFD);
00425 
00426 //-----------------------------------------------------------------------------
00428 //-----------------------------------------------------------------------------
00429 
00430 virtual ~Poller() {}
00431 
00432 protected:
00433 struct  PipeData;
00434 
00435         void  CbkTMO();
00436         bool  CbkXeq(Channel *cP, int events, int eNum, const char *eTxt);
00437 inline  int   GetFault(Channel *cP)   {return cP->chFault;}
00438 inline  int   GetPollEnt(Channel *cP) {return cP->pollEnt;}
00439         int   GetRequest();
00440         bool  Init(Channel *cP, int &eNum, const char **eTxt, bool &isLockd);
00441 inline  void  LockChannel(Channel *cP) {cP->chMutex.Lock();}
00442         int   Poll2Enum(short events);
00443         int   SendCmd(PipeData &cmd);
00444         void  SetPollEnt(Channel *cP, int ptEnt);
00445         bool  TmoAdd(Channel *cP, int tmoSet);
00446         void  TmoDel(Channel *cP);
00447         int   TmoGet();
00448 inline  void  UnLockChannel(Channel *cP) {cP->chMutex.UnLock();}
00449 
00453 virtual void Begin(XrdSysSemaphore *syncp, int &rc, const char **eTxt) = 0;
00454 
00459 virtual void Exclude(Channel *cP, bool &isLocked, bool dover=1) = 0;
00460 
00465 virtual bool Include(Channel     *cP,
00466                      int         &eNum,
00467                      const char **eTxt,
00468                      bool        &isLocked) = 0;
00469 
00474 virtual bool Modify (Channel     *cP,
00475                      int         &eNum,
00476                      const char **eTxt,
00477                      bool        &isLocked) = 0;
00478 
00483 //
00484 virtual void Shutdown() = 0;
00485 
00486 // The following is common to all implementations
00487 //
00488 Channel        *attBase;    // -> First channel in attach  queue or 0
00489 Channel        *tmoBase;    // -> First channel in timeout queue or 0
00490 
00491 pthread_t       pollTid;    // Poller's thread ID
00492 
00493 struct pollfd   pipePoll;   // Stucture to wait for pipe events
00494 int             cmdFD;      // FD to send PipeData commands
00495 int             reqFD;      // FD to recv PipeData requests
00496 struct          PipeData {char req; char evt; short ent; int fd;
00497                           XrdSysSemaphore *theSem;
00498                           enum cmd {NoOp = 0, MdFD = 1, Post = 2,
00499                                     MiFD = 3, RmFD = 4, Stop = 5};
00500                           PipeData(char reQ=0, char evT=0, short enT=0,
00501                                    int  fD =0, XrdSysSemaphore *sP=0)
00502                                   : req(reQ), evt(evT), ent(enT), fd(fD),
00503                                     theSem(sP) {}
00504                          ~PipeData() {}
00505                          };
00506 PipeData        reqBuff;    // Buffer used by poller thread to recv data
00507 char           *pipeBuff;   // Read resumption point in buffer
00508 int             pipeBlen;   // Number of outstanding bytes
00509 char            tmoMask;    // Timeout mask
00510 CPP_ATOMIC_TYPE(bool) wakePend;   // Wakeup is effectively pending (don't send)
00511 bool            chDead;     // True if channel deleted by callback
00512 
00513 static time_t   maxTime;    // Maximum time allowed
00514 
00515 private:
00516 
00517 void Attach(Channel *cP);
00518 void Detach(Channel *cP, bool &isLocked, bool keep=true);
00519 void WakeUp();
00520 
00521 // newPoller() called to get a specialized new poll object at in response to
00522 //             Create(). A specialized implementation must be supplied.
00523 //
00524 static Poller *newPoller(int pFD[2], int &eNum, const char **eTxt);
00525 
00526 XrdSysMutex    adMutex; // Mutex for adding & detaching channels
00527 XrdSysMutex    toMutex; // Mutex for handling the timeout list
00528 };
00529 };
00530 };
00531 #endif

Generated on 13 Mar 2017 for xrootd by  doxygen 1.4.7