xrootd
XrdSysIOEvents.hh
Go to the documentation of this file.
1 #ifndef __XRDSYSIOEVENTS_HH__
2 #define __XRDSYSIOEVENTS_HH__
3 /******************************************************************************/
4 /* */
5 /* X r d S y s I O E v e n t s . h h */
6 /* */
7 /* (c) 2012 by the Board of Trustees of the Leland Stanford, Jr., University */
8 /* All Rights Reserved */
9 /* Produced by Andrew Hanushevsky for Stanford University under contract */
10 /* DE-AC02-76-SFO0515 with the Department of Energy */
11 /* */
12 /* This file is part of the XRootD software suite. */
13 /* */
14 /* XRootD is free software: you can redistribute it and/or modify it under */
15 /* the terms of the GNU Lesser General Public License as published by the */
16 /* Free Software Foundation, either version 3 of the License, or (at your */
17 /* option) any later version. */
18 /* */
19 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
20 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
21 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
22 /* License for more details. */
23 /* */
24 /* You should have received a copy of the GNU Lesser General Public License */
25 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
26 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
27 /* */
28 /* The copyright holder's institutional names and contributor's names may not */
29 /* be used to endorse or promote products derived from this software without */
30 /* specific prior written permission of the institution or contributor. */
31 /******************************************************************************/
32 
33 #include <poll.h>
34 #include <time.h>
35 #include <sys/types.h>
36 
37 #include "XrdSys/XrdSysPthread.hh"
38 
39 //-----------------------------------------------------------------------------
53 //-----------------------------------------------------------------------------
54 
55 namespace XrdSys
56 {
57 namespace IOEvents
58 {
59 
60 /******************************************************************************/
61 /* C l a s s C a l l B a c k */
62 /******************************************************************************/
63 
64 //-----------------------------------------------------------------------------
74 //-----------------------------------------------------------------------------
75 
76 class Channel;
77 class CallBack
78 {
79 public:
80 
81 //-----------------------------------------------------------------------------
83 //-----------------------------------------------------------------------------
84 
85  enum EventType
86  {
87  ReadyToRead = 0x01,
88  ReadTimeOut = 0x02,
89  ReadyToWrite = 0x04,
90  WriteTimeOut = 0x08
91  };
92 
93 //-----------------------------------------------------------------------------
110 //-----------------------------------------------------------------------------
111 
112 virtual bool Event(Channel *chP, void *cbArg, int evFlags) = 0;
113 
114 //-----------------------------------------------------------------------------
125 //-----------------------------------------------------------------------------
126 
127 virtual void Fatal(Channel *chP, void *cbArg, int eNum, const char *eTxt) {};
128 
129 //-----------------------------------------------------------------------------
137 //-----------------------------------------------------------------------------
138 
139 virtual void Stop(Channel *chP, void *cbArg) {}
140 
141 //-----------------------------------------------------------------------------
143 //-----------------------------------------------------------------------------
144 
145  CallBack() {}
146 
147 //-----------------------------------------------------------------------------
149 //-----------------------------------------------------------------------------
150 
151 virtual ~CallBack() {}
152 };
153 
154 /******************************************************************************/
155 /* C l a s s C h a n n e l */
156 /******************************************************************************/
157 
158 //-----------------------------------------------------------------------------
162 //-----------------------------------------------------------------------------
163 
164 class ChannelWait;
165 class Poller;
166 class Channel
167 {
168 friend class Poller;
169 public:
170 
171 //-----------------------------------------------------------------------------
173 //-----------------------------------------------------------------------------
174 
175 enum EventCode {readEvents = 0x01,
176  writeEvents = 0x04,
177  rwEvents = 0x05,
178  errorEvents = 0x10,
179  stopEvent = 0x20,
180  allEvents = 0x35
181  };
182 
183 //-----------------------------------------------------------------------------
193 //-----------------------------------------------------------------------------
194 
195  bool Disable(int events, const char **eText=0);
196 
197 //-----------------------------------------------------------------------------
229 //-----------------------------------------------------------------------------
230 
231  bool Enable(int events, int timeout=0, const char **eText=0);
232 
233 //-----------------------------------------------------------------------------
238 //-----------------------------------------------------------------------------
239 
240  void GetCallBack(CallBack **cbP, void **cbArg);
241 
242 //-----------------------------------------------------------------------------
248 //-----------------------------------------------------------------------------
249 
250  int GetEvents() {return (chPoller ? static_cast<int>(chEvents) : -1);}
251 
252 //-----------------------------------------------------------------------------
257 //-----------------------------------------------------------------------------
258 
259  int GetFD() {return chFD;}
260 
261 //-----------------------------------------------------------------------------
268 //-----------------------------------------------------------------------------
269 
270  void SetCallBack(CallBack *cbP, void *cbArg=0);
271 
272 //-----------------------------------------------------------------------------
281 //-----------------------------------------------------------------------------
282 
283  void SetFD(int fd);
284 
285 //-----------------------------------------------------------------------------
300 //-----------------------------------------------------------------------------
301 
302  Channel(Poller *pollP, int fd, CallBack *cbP=0, void *cbArg=0);
303 
304 //-----------------------------------------------------------------------------
308 //-----------------------------------------------------------------------------
309 
310  ~Channel();
311 
312 private:
313 
314 struct dlQ {Channel *next; Channel *prev;};
315 
317 
318 dlQ attList; // List of attached channels
319 dlQ tmoList; // List of channels in the timeout queue
320 
321 Poller *chPoller; // The effective poller
322 Poller *chPollXQ; // The real poller
323 CallBack *chCB; // CallBack function
324 void *chCBA; // CallBack argument
325 int chFD; // Associated file descriptor
326 int pollEnt; // Used only for poll() type pollers
327 int chRTO; // Read timeout value (0 means none)
328 int chWTO; // Write timeout value (0 means none)
329 time_t rdDL; // Read deadline
330 time_t wrDL; // Write deadline
331 time_t deadLine; // The deadline in effect (read or write)
332 char dlType; // The deadline type in deadLine as CallBack type
333 char chEvents; // Enabled events as Channel type
334 char chStat; // Channel status below (!0 -> in callback mode)
336 char inTOQ; // True if the channel is in the timeout queue
337 char inPSet; // FD is in the actual poll set
338 char reMod; // Modify issued while defered, re-issue needed
339 short chFault; // Defered error, 0 if all is well
340 
341 void Reset(Poller *thePoller, int fd, int eNum=0);
342 };
343 
344 /******************************************************************************/
345 /* C l a s s P o l l e r */
346 /******************************************************************************/
347 
348 //-----------------------------------------------------------------------------
354 //-----------------------------------------------------------------------------
355 
356 class Poller
357 {
358 friend class BootStrap;
359 friend class Channel;
360 public:
361 
362 //-----------------------------------------------------------------------------
376 //-----------------------------------------------------------------------------
377 
378 static Poller *Create(int &eNum, const char **eTxt=0);
379 
380 //-----------------------------------------------------------------------------
391 //-----------------------------------------------------------------------------
392 
393  void Stop();
394 
395 //-----------------------------------------------------------------------------
400 //-----------------------------------------------------------------------------
401 
402  Poller(int cFD, int rFD);
403 
404 //-----------------------------------------------------------------------------
406 //-----------------------------------------------------------------------------
407 
408 virtual ~Poller() {}
409 
410 protected:
411 struct PipeData;
412 
413  void CbkTMO();
414  bool CbkXeq(Channel *cP, int events, int eNum, const char *eTxt);
415 inline int GetFault(Channel *cP) {return cP->chFault;}
416 inline int GetPollEnt(Channel *cP) {return cP->pollEnt;}
417  int GetRequest();
418  bool Init(Channel *cP, int &eNum, const char **eTxt, bool &isLockd);
419 inline void LockChannel(Channel *cP) {cP->chMutex.Lock();}
420  int Poll2Enum(short events);
421  int SendCmd(PipeData &cmd);
422  void SetPollEnt(Channel *cP, int ptEnt);
423  bool TmoAdd(Channel *cP);
424  void TmoDel(Channel *cP);
425  int TmoGet();
426 inline void UnLockChannel(Channel *cP) {cP->chMutex.UnLock();}
427 
431 virtual void Begin(XrdSysSemaphore *syncp, int &rc, const char **eTxt) = 0;
432 
437 virtual void Exclude(Channel *cP, bool &isLocked, bool dover=1) = 0;
438 
443 virtual bool Include(Channel *cP,
444  int &eNum,
445  const char **eTxt,
446  bool &isLocked) = 0;
447 
452 virtual bool Modify (Channel *cP,
453  int &eNum,
454  const char **eTxt,
455  bool &isLocked) = 0;
456 
461 //
462 virtual void Shutdown() = 0;
463 
464 // The following is common to all implementations
465 //
466 Channel *attBase; // -> First channel in attach queue or 0
467 Channel *tmoBase; // -> First channel in timeout queue or 0
468 
469 pthread_t pollTid; // Poller's thread ID
470 
471 struct pollfd pipePoll; // Stucture to wait for pipe events
472 int cmdFD; // FD to send PipeData commands
473 int reqFD; // FD to recv PipeData requests
474 struct PipeData {char req; char evt; short ent; int fd;
476  enum cmd {NoOp = 0, MdFD = 1, Post = 2,
477  MiFD = 3, RmFD = 4, Stop = 5};
478  };
479 PipeData reqBuff; // Buffer used by poller thread to recv data
480 char *pipeBuff; // Read resumption point in buffer
481 int pipeBlen; // Number of outstanding bytes
482 bool wakePend; // Wakeup is effectively pending (don't send)
483 bool chDead; // True if channel deleted by callback
484 
485 static time_t maxTime; // Maximum time allowed
486 
487 private:
488 
489 void Attach(Channel *cP);
490 void Detach(Channel *cP, bool &isLocked, bool keep=true);
491 void WakeUp();
492 
493 // newPoller() called to get a specialized new poll object at in response to
494 // Create(). A specialized implementation must be supplied.
495 //
496 static Poller *newPoller(int pFD[2], int &eNum, const char **eTxt);
497 
498 XrdSysMutex adMutex; // Mutex for adding & detaching channels
499 XrdSysMutex toMutex; // Mutex for handling the timeout list
500 };
501 };
502 };
503 #endif