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 //-----------------------------------------------------------------------------
00137 //-----------------------------------------------------------------------------
00138 
00139 virtual void Stop(Channel *chP, void *cbArg) {}
00140 
00141 //-----------------------------------------------------------------------------
00143 //-----------------------------------------------------------------------------
00144 
00145             CallBack() {}
00146 
00147 //-----------------------------------------------------------------------------
00149 //-----------------------------------------------------------------------------
00150 
00151 virtual    ~CallBack() {}
00152 };
00153 
00154 /******************************************************************************/
00155 /*                         C l a s s   C h a n n e l                          */
00156 /******************************************************************************/
00157 
00158 //-----------------------------------------------------------------------------
00162 //-----------------------------------------------------------------------------
00163   
00164 class ChannelWait;
00165 class Poller;
00166 class Channel
00167 {
00168 friend class Poller;
00169 public:
00170 
00171 //-----------------------------------------------------------------------------
00173 //-----------------------------------------------------------------------------
00174 
00175 enum EventCode {readEvents  = 0x01, 
00176                 writeEvents = 0x04, 
00177                 rwEvents    = 0x05, 
00178                 errorEvents = 0x10, 
00179                 stopEvent   = 0x20, 
00180                 allEvents   = 0x35  
00181                };
00182 
00183 //-----------------------------------------------------------------------------
00193 //-----------------------------------------------------------------------------
00194 
00195         bool Disable(int events, const char **eText=0);
00196 
00197 //-----------------------------------------------------------------------------
00229 //-----------------------------------------------------------------------------
00230 
00231         bool Enable(int events, int timeout=0, const char **eText=0);
00232 
00233 //-----------------------------------------------------------------------------
00238 //-----------------------------------------------------------------------------
00239 
00240         void GetCallBack(CallBack **cbP, void **cbArg);
00241 
00242 //-----------------------------------------------------------------------------
00248 //-----------------------------------------------------------------------------
00249 
00250         int  GetEvents() {return (chPoller ? static_cast<int>(chEvents) : -1);}
00251 
00252 //-----------------------------------------------------------------------------
00257 //-----------------------------------------------------------------------------
00258 
00259         int  GetFD() {return chFD;}
00260 
00261 //-----------------------------------------------------------------------------
00268 //-----------------------------------------------------------------------------
00269 
00270         void SetCallBack(CallBack *cbP, void *cbArg=0);
00271 
00272 //-----------------------------------------------------------------------------
00281 //-----------------------------------------------------------------------------
00282 
00283         void SetFD(int fd);
00284 
00285 //-----------------------------------------------------------------------------
00300 //-----------------------------------------------------------------------------
00301 
00302       Channel(Poller *pollP, int fd, CallBack *cbP=0, void *cbArg=0);
00303 
00304 //-----------------------------------------------------------------------------
00308 //-----------------------------------------------------------------------------
00309 
00310      ~Channel();
00311 
00312 private:
00313 
00314 struct dlQ {Channel *next; Channel *prev;};
00315 
00316 XrdSysRecMutex chMutex;
00317 
00318 dlQ            attList;     // List of attached channels
00319 dlQ            tmoList;     // List of channels in the timeout queue
00320 
00321 Poller        *chPoller;    // The effective poller
00322 Poller        *chPollXQ;    // The real      poller
00323 CallBack      *chCB;        // CallBack function
00324 void          *chCBA;       // CallBack argument
00325 int            chFD;        // Associated file descriptor
00326 int            pollEnt;     // Used only for poll() type pollers
00327 int            chRTO;       // Read  timeout value (0 means none)
00328 int            chWTO;       // Write timeout value (0 means none)
00329 time_t         rdDL;        // Read  deadline
00330 time_t         wrDL;        // Write deadline
00331 time_t         deadLine;    // The deadline in effect (read or write)
00332 char           dlType;      // The deadline type in deadLine as CallBack type
00333 char           chEvents;    // Enabled events as Channel type
00334 char           chStat;      // Channel status below (!0 -> in callback mode)
00335 enum Status   {isClear = 0, isCBMode, isDead};
00336 char           inTOQ;       // True if the channel is in the timeout queue
00337 char           inPSet;      // FD is in the actual poll set
00338 char           reMod;       // Modify issued while defered, re-issue needed
00339 short          chFault;     // Defered error, 0 if all is well
00340 
00341 void           Reset(Poller *thePoller, int fd, int eNum=0);
00342 };
00343 
00344 /******************************************************************************/
00345 /*                          C l a s s   P o l l e r                           */
00346 /******************************************************************************/
00347   
00348 //-----------------------------------------------------------------------------
00354 //-----------------------------------------------------------------------------
00355 
00356 class Poller
00357 {
00358 friend class BootStrap;
00359 friend class Channel;
00360 public:
00361 
00362 //-----------------------------------------------------------------------------
00376 //-----------------------------------------------------------------------------
00377 
00378 static Poller     *Create(int &eNum, const char **eTxt=0);
00379 
00380 //-----------------------------------------------------------------------------
00391 //-----------------------------------------------------------------------------
00392 
00393        void        Stop();
00394 
00395 //-----------------------------------------------------------------------------
00400 //-----------------------------------------------------------------------------
00401 
00402          Poller(int cFD, int rFD);
00403 
00404 //-----------------------------------------------------------------------------
00406 //-----------------------------------------------------------------------------
00407 
00408 virtual ~Poller() {}
00409 
00410 protected:
00411 struct  PipeData;
00412 
00413         void  CbkTMO();
00414         bool  CbkXeq(Channel *cP, int events, int eNum, const char *eTxt);
00415 inline  int   GetFault(Channel *cP)   {return cP->chFault;}
00416 inline  int   GetPollEnt(Channel *cP) {return cP->pollEnt;}
00417         int   GetRequest();
00418         bool  Init(Channel *cP, int &eNum, const char **eTxt, bool &isLockd);
00419 inline  void  LockChannel(Channel *cP) {cP->chMutex.Lock();}
00420         int   Poll2Enum(short events);
00421         int   SendCmd(PipeData &cmd);
00422         void  SetPollEnt(Channel *cP, int ptEnt);
00423         bool  TmoAdd(Channel *cP);
00424         void  TmoDel(Channel *cP);
00425         int   TmoGet();
00426 inline  void  UnLockChannel(Channel *cP) {cP->chMutex.UnLock();}
00427 
00431 virtual void Begin(XrdSysSemaphore *syncp, int &rc, const char **eTxt) = 0;
00432 
00437 virtual void Exclude(Channel *cP, bool &isLocked, bool dover=1) = 0;
00438 
00443 virtual bool Include(Channel     *cP,
00444                      int         &eNum,
00445                      const char **eTxt,
00446                      bool        &isLocked) = 0;
00447 
00452 virtual bool Modify (Channel     *cP,
00453                      int         &eNum,
00454                      const char **eTxt,
00455                      bool        &isLocked) = 0;
00456 
00461 //
00462 virtual void Shutdown() = 0;
00463 
00464 // The following is common to all implementations
00465 //
00466 Channel        *attBase;    // -> First channel in attach  queue or 0
00467 Channel        *tmoBase;    // -> First channel in timeout queue or 0
00468 
00469 pthread_t       pollTid;    // Poller's thread ID
00470 
00471 struct pollfd   pipePoll;   // Stucture to wait for pipe events
00472 int             cmdFD;      // FD to send PipeData commands
00473 int             reqFD;      // FD to recv PipeData requests
00474 struct          PipeData {char req; char evt; short ent; int fd;
00475                           XrdSysSemaphore *theSem;
00476                           enum cmd {NoOp = 0, MdFD = 1, Post = 2,
00477                                     MiFD = 3, RmFD = 4, Stop = 5};
00478                          };
00479 PipeData        reqBuff;    // Buffer used by poller thread to recv data
00480 char           *pipeBuff;   // Read resumption point in buffer
00481 int             pipeBlen;   // Number of outstanding bytes
00482 bool            wakePend;   // Wakeup is effectively pending (don't send)
00483 bool            chDead;     // True if channel deleted by callback
00484 
00485 static time_t   maxTime;    // Maximum time allowed
00486 
00487 private:
00488 
00489 void Attach(Channel *cP);
00490 void Detach(Channel *cP, bool &isLocked, bool keep=true);
00491 void WakeUp();
00492 
00493 // newPoller() called to get a specialized new poll object at in response to
00494 //             Create(). A specialized implementation must be supplied.
00495 //
00496 static Poller *newPoller(int pFD[2], int &eNum, const char **eTxt);
00497 
00498 XrdSysMutex    adMutex; // Mutex for adding & detaching channels
00499 XrdSysMutex    toMutex; // Mutex for handling the timeout list
00500 };
00501 };
00502 };
00503 #endif

Generated on 27 Jul 2013 for xrootd by  doxygen 1.4.7