XRootD
XrdSys::IOEvents::PollE Class Reference
+ Inheritance diagram for XrdSys::IOEvents::PollE:
+ Collaboration diagram for XrdSys::IOEvents::PollE:

Public Member Functions

 PollE (struct epoll_event *ptab, int numfd, int pfd, int pFD[2])
 
 ~PollE ()
 
- Public Member Functions inherited from XrdSys::IOEvents::Poller
 Poller (int cFD, int rFD)
 
virtual ~Poller ()
 Destructor. Stop() is effecively called when this object is deleted. More...
 
void Stop ()
 

Static Public Member Functions

static int AllocMem (void **memP, int slots)
 
- Static Public Member Functions inherited from XrdSys::IOEvents::Poller
static PollerCreate (int &eNum, const char **eTxt=0, int crOpts=0)
 

Protected Member Functions

void Begin (XrdSysSemaphore *syncp, int &rc, const char **eMsg)
 
void Exclude (Channel *cP, bool &isLocked, bool dover=1)
 
bool Include (Channel *cP, int &eNum, const char **eTxt, bool &isLocked)
 
bool Modify (Channel *cP, int &eNum, const char **eTxt, bool &isLocked)
 
void Shutdown ()
 
- Protected Member Functions inherited from XrdSys::IOEvents::Poller
void CbkTMO ()
 
bool CbkXeq (Channel *cP, int events, int eNum, const char *eTxt)
 
 CPP_ATOMIC_TYPE (bool) wakePend
 
int GetFault (Channel *cP)
 
int GetPollEnt (Channel *cP)
 
int GetRequest ()
 
bool Init (Channel *cP, int &eNum, const char **eTxt, bool &isLockd)
 
void LockChannel (Channel *cP)
 
int Poll2Enum (short events)
 
int SendCmd (PipeData &cmd)
 
void SetPollEnt (Channel *cP, int ptEnt)
 
bool TmoAdd (Channel *cP, int tmoSet)
 
void TmoDel (Channel *cP)
 
int TmoGet ()
 
void UnLockChannel (Channel *cP)
 

Additional Inherited Members

- Public Types inherited from XrdSys::IOEvents::Poller
enum  CreateOpts { optTOM }
 
- Protected Attributes inherited from XrdSys::IOEvents::Poller
ChannelattBase
 
bool chDead
 
int cmdFD
 
int pipeBlen
 
char * pipeBuff
 
struct pollfd pipePoll
 
pthread_t pollTid
 
PipeData reqBuff
 
int reqFD
 
ChanneltmoBase
 
unsigned char tmoMask
 
- Static Protected Attributes inherited from XrdSys::IOEvents::Poller
static time_t maxTime = (sizeof(time_t) == 8 ? 0x7fffffffffffffffLL : 0x7fffffff)
 
static pid_t parentPID = getpid()
 

Detailed Description

Definition at line 51 of file XrdSysIOEventsPollE.icc.

Constructor & Destructor Documentation

◆ PollE()

XrdSys::IOEvents::PollE::PollE ( struct epoll_event *  ptab,
int  numfd,
int  pfd,
int  pFD[2] 
)
inline

Definition at line 57 of file XrdSysIOEventsPollE.icc.

58  : Poller(pFD[0], pFD[1]), pollTab(ptab), cbNow(0),
59  pollDfd(pfd), pollMax(numfd), pollNum(1), numPoll(0),
60  cbCurr(0)
61  {}
Poller(int cFD, int rFD)

◆ ~PollE()

XrdSys::IOEvents::PollE::~PollE ( )
inline

Definition at line 62 of file XrdSysIOEventsPollE.icc.

References XrdSys::IOEvents::Poller::Stop().

+ Here is the call graph for this function:

Member Function Documentation

◆ AllocMem()

int XrdSys::IOEvents::PollE::AllocMem ( void **  memP,
int  slots 
)
static

Definition at line 153 of file XrdSysIOEventsPollE.icc.

154 {
155  int rc, bytes, alignment, pagsz = getpagesize();
156 
157 // Calculate the size of the poll table and allocate it
158 //
159  bytes = slots * sizeof(struct epoll_event);
160  alignment = (bytes < pagsz ? 1024 : pagsz);
161  if (!(rc = posix_memalign(memP, alignment, bytes))) memset(*memP, 0, bytes);
162  return rc;
163 }

◆ Begin()

void XrdSys::IOEvents::PollE::Begin ( XrdSysSemaphore syncp,
int &  rc,
const char **  eTxt 
)
protectedvirtual

Start the polling event loop. An implementation must be supplied. Begin() is called via the internal BootStrap class from a new thread.

Implements XrdSys::IOEvents::Poller.

Definition at line 195 of file XrdSysIOEventsPollE.icc.

198 {
199  int numpolled, pollN;
200  Channel *cP;
201 
202 // Indicate to the starting thread that all went well
203 //
204  retcode = 0;
205  *eTxt = 0;
206  syncsem->Post();
207 
208 // Now start dispatching channels that are ready. We use the wakePend flag to
209 // keep the chatter down when we actually wakeup.
210 //
211  do {do {numpolled = epoll_wait(pollDfd, pollTab, pollMax, TmoGet());}
212  while (numpolled < 0 && errno == EINTR);
213  CPP_ATOMIC_STORE(wakePend, true, std::memory_order_release);
214  numPoll = numpolled;
215  if (numpolled == 0) CbkTMO();
216  else if (numpolled < 0)
217  {int rc = errno;
218  //--------------------------------------------------------------
219  // If we are in a child process and the epoll file descriptor
220  // has been closed, there is an immense chance the fork will be
221  // followed by an exec, in which case we don't want to abort
222  //--------------------------------------------------------------
223  if( rc == EBADF && parentPID != getpid() ) return;
224  std::cerr <<"EPoll: "<<XrdSysE2T(rc)<<" polling for events "<<std::endl;
225  abort();
226  }
227  else for (int i = 0; i < numpolled; i++)
228  {if ((cP = (Channel *)pollTab[i].data.ptr))
229  {cbCurr = i; Dispatch(cP, pollTab[i].events);}
230  else if (!Process(i)) return;
231  }
232 
233  pollN = AtomicGet(pollNum);
234  if (pollMax < pollN) AllocPT(pollN);
235 
236  } while(1);
237 }
#define CPP_ATOMIC_STORE(x, val, order)
#define AtomicGet(x)
const char * XrdSysE2T(int errcode)
Definition: XrdSysE2T.cc:104

References AtomicGet, CPP_ATOMIC_STORE, XrdSysSemaphore::Post(), and XrdSysE2T().

+ Here is the call graph for this function:

◆ Exclude()

void XrdSys::IOEvents::PollE::Exclude ( Channel cP,
bool &  isLocked,
bool  dover = 1 
)
protectedvirtual

Remove a channel to the poll set. An implementation must be supplied. The channel is locked when this method is called but must be unlocked by the method if a command is sent to the poller thread and isLocked set to false.

Implements XrdSys::IOEvents::Poller.

Definition at line 282 of file XrdSysIOEventsPollE.icc.

284 {
285 
286 // Remove this channel from the poll set. We ignore errors as the descriptor
287 // may have been closed prior to this call (though this shouldn't happen).
288 //
289  epoll_ctl(pollDfd, EPOLL_CTL_DEL, cP->GetFD(), 0);
290  AtomicDec(pollNum);
291 
292 // If we need to verify this action, sync with the poller thread (note that the
293 // poller thread will not ask for this action unless it wants to deadlock). We
294 // may actually deadlock anyway if the channel lock is held. We are allowed to
295 // release it if the caller locked it. This will prevent a deadlock. Otherwise,
296 // if we are in a callback and this channel is not the one that initiated the
297 // exclude then we must make sure that we cancel any pending callback to the
298 // excluded channel as it may have been deleted and we won't know that here.
299 //
300  if (dover)
301  {PipeData cmdbuff;
302  if (isLocked)
303  {isLocked = false;
304  UnLockChannel(cP);
305  }
306  cmdbuff.req = PipeData::RmFD;
307  cmdbuff.fd = cP->GetFD();
308  SendCmd(cmdbuff);
309  } else {
310  if (cbNow && cbNow != cP)
311  for (int i = cbCurr+1; i < numPoll; i++)
312  {if (cP == (Channel *)pollTab[i].data.ptr)
313  pollTab[i].data.ptr = &deadChP;
314  }
315  }
316 }
#define AtomicDec(x)
int SendCmd(PipeData &cmd)
void UnLockChannel(Channel *cP)

References AtomicDec, XrdSys::IOEvents::Poller::PipeData::fd, XrdSys::IOEvents::Channel::GetFD(), and XrdSys::IOEvents::Poller::PipeData::req.

+ Here is the call graph for this function:

◆ Include()

bool XrdSys::IOEvents::PollE::Include ( Channel cP,
int &  eNum,
const char **  eTxt,
bool &  isLocked 
)
protectedvirtual

Add a channel to the poll set. An implementation must be supplied. The channel is locked when this method is called but must be unlocked by the method if a command is sent to the poller thread and isLocked set to false.

Implements XrdSys::IOEvents::Poller.

Definition at line 322 of file XrdSysIOEventsPollE.icc.

326 {
327  struct epoll_event myEvent = {0, {(void *)cP}};
328  int events = cP->GetEvents();
329 
330 // Establish new event mask
331 //
332  if (events & Channel:: readEvents) myEvent.events = EPOLLIN | EPOLLPRI;
333  if (events & Channel::writeEvents) myEvent.events |= EPOLLOUT;
334 
335 // Add this fd to the poll set
336 //
337  if (epoll_ctl(pollDfd, EPOLL_CTL_ADD, cP->GetFD(), &myEvent))
338  {eNum = errno;
339  if (eTxt) *eTxt = "adding channel";
340  return false;
341  }
342 
343 // All went well. Bump the number in the set. The poller thread will
344 // reallocate the poll table if need be.
345 //
346  AtomicInc(pollNum);
347  return true;
348 }
#define AtomicInc(x)
@ writeEvents
Write and Write Timeouts.
@ readEvents
Read and Read Timeouts.

References AtomicInc, XrdSys::IOEvents::Channel::GetEvents(), XrdSys::IOEvents::Channel::GetFD(), XrdSys::IOEvents::Channel::readEvents, and XrdSys::IOEvents::Channel::writeEvents.

+ Here is the call graph for this function:

◆ Modify()

bool XrdSys::IOEvents::PollE::Modify ( Channel cP,
int &  eNum,
const char **  eTxt,
bool &  isLocked 
)
protectedvirtual

Modify the event status of a channel. An implementation must be supplied. The channel is locked when this method is called but must be unlocked by the method if a command is sent to the poller thread and isLocked set to false.

Implements XrdSys::IOEvents::Poller.

Definition at line 354 of file XrdSysIOEventsPollE.icc.

358 {
359  struct epoll_event myEvents = {0, {(void *)cP}};
360  int events = cP->GetEvents();
361 
362 // Establish new event mask
363 //
364  if (events & Channel:: readEvents) myEvents.events |= EPOLLIN | EPOLLPRI;
365  if (events & Channel::writeEvents) myEvents.events |= EPOLLOUT;
366 
367 // Modify this fd. Unlike solaris, epoll_ctl() does not block when the pollfd
368 // is being waited upon by another thread.
369 //
370  if (epoll_ctl(pollDfd, EPOLL_CTL_MOD, cP->GetFD(), &myEvents))
371  {eNum = errno;
372  if (eTxt) *eTxt = "modifying poll events";
373  return false;
374  }
375 
376 // All done
377 //
378  return true;
379 }

References XrdSys::IOEvents::Channel::GetEvents(), XrdSys::IOEvents::Channel::GetFD(), XrdSys::IOEvents::Channel::readEvents, and XrdSys::IOEvents::Channel::writeEvents.

+ Here is the call graph for this function:

◆ Shutdown()

void XrdSys::IOEvents::PollE::Shutdown ( )
protectedvirtual

Shutdown the poller. An implementation must be supplied. The shutdown method must release any allocated storage and close private file descriptors. The polling thread will have already been terminated and x-thread pipe closed. Warning: the derived destructor must call Stop() and do nothing else!

Implements XrdSys::IOEvents::Poller.

Definition at line 413 of file XrdSysIOEventsPollE.icc.

414 {
415  static XrdSysMutex shutMutex;
416 
417 // To avoid race conditions, we serialize this code
418 //
419  shutMutex.Lock();
420 
421 // Release the poll table
422 //
423  if (pollTab) {free(pollTab); pollTab = 0;}
424 
425 // Close the epoll file descriptor
426 //
427  if (pollDfd >= 0) {close(pollDfd); pollDfd = -1;}
428 
429 // All done
430 //
431  shutMutex.UnLock();
432 }
#define close(a)
Definition: XrdPosix.hh:43

References close, XrdSysMutex::Lock(), and XrdSysMutex::UnLock().

+ Here is the call graph for this function:

The documentation for this class was generated from the following file: