XRootD
Loading...
Searching...
No Matches
XrdSys::IOEvents::PollPoll Class Reference
Inheritance diagram for XrdSys::IOEvents::PollPoll:
Collaboration diagram for XrdSys::IOEvents::PollPoll:

Public Member Functions

 PollPoll (int &rc, int numfd, int pFD[2])
 ~PollPoll ()
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.
void Stop ()

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 }
Static Public Member Functions inherited from XrdSys::IOEvents::Poller
static PollerCreate (int &eNum, const char **eTxt=0, int crOpts=0)
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 49 of file XrdSysIOEventsPollPoll.icc.

Constructor & Destructor Documentation

◆ PollPoll()

XrdSys::IOEvents::PollPoll::PollPoll ( int & rc,
int numfd,
int pFD[2] )

Definition at line 122 of file XrdSysIOEventsPollPoll.icc.

123 : Poller(pFD[0], pFD[1])
124{
125 int i;
126
127// Allocate initial poll table
128//
129 if (!(pollTab = (struct pollfd *)malloc(numfd*sizeof(struct pollfd))))
130 {rc = errno; return;}
131
132// Initialize it
133//
134 for (i = 1; i < numfd; i++)
135 {pollTab[i].fd = -1; pollTab[i].events = 0; pollTab[i].revents = 0;}
136
137// The first element of the poll tab is the communications pipe
138//
139 pollTab[0].fd = pFD[0];
140 pollTab[0].events = POLLIN | POLLRDNORM;
141 pollTab[0].revents = 0;
142
143// Initialize remaining poll data
144//
145 pollNum = 1;
146 pollMax = numfd;
147 pnewTab = 0;
148
149// Allocate initial channel table
150//
151 if (!(chnlTab = (Channel **)malloc(numfd*sizeof(Channel *))))
152 {rc = errno; return;}
153
154// Initialize it
155//
156 memset(chnlTab, 0, numfd*sizeof(Channel *));
157 chnlMax = numfd;
158 chnlNum = 1;
159
160// All done
161//
162 rc = 0;
163}

References XrdSys::IOEvents::Poller::Poller(), and XrdSys::IOEvents::Poller::Channel.

Here is the call graph for this function:

◆ ~PollPoll()

XrdSys::IOEvents::PollPoll::~PollPoll ( )
inline

Definition at line 54 of file XrdSysIOEventsPollPoll.icc.

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

Here is the call graph for this function:

Member Function Documentation

◆ Begin()

void XrdSys::IOEvents::PollPoll::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 169 of file XrdSysIOEventsPollPoll.icc.

172{
173 int i, num2poll, numpolled;
174
175// Indicate to the starting thread that all went well
176//
177 retcode = 0;
178 *eTxt = 0;
179 syncsem->Post();
180
181// Now start dispatching channels that are ready. We use the wakePend flag to
182// keep the chatter down when we actually wakeup.
183//
184 pollMutex.Lock();
185 do {num2poll = pollNum;
186 pollMutex.UnLock();
187 do {numpolled = poll(pollTab, num2poll, TmoGet());}
188 while(numpolled < 0 && (errno == EAGAIN || errno == EINTR));
189 pollMutex.Lock();
190 wakePend = true;
191
192 if (pnewTab)
193 {memcpy(pnewTab, pollTab, pollMax*sizeof(struct pollfd));
194 free(pollTab); pollTab = pnewTab; pnewTab = 0; pollMax = chnlMax;
195 }
196
197 if (numpolled == 0) CbkTMO();
198 else if (numpolled < 0)
199 {int rc = errno;
200 //--------------------------------------------------------------
201 // If we are in a child process and the poll file descriptor
202 // has been closed, there is an immense chance the fork will be
203 // followed by an exec, in which case we don't want to abort
204 //--------------------------------------------------------------
205 if( rc == EBADF && parentPID != getpid() ) return;
206 std::cerr <<"PPoll: "<<XrdSysE2T(rc)<<" polling for events"<<std::endl;
207 abort();
208 }
209 else{if (pollTab[0].revents) numpolled--;
210 for (i = 1; i < num2poll && numpolled; i++)
211 {if (pollTab[i].revents)
212 {numpolled--;
213 Dispatch(i, pollTab[i].revents);
214 }
215 }
216 if (pollTab[0].revents && !Process()) return;
217 }
218 } while(1);
219}
const char * XrdSysE2T(int errcode)
Definition XrdSysE2T.cc:104

References XrdSys::IOEvents::Poller::CbkTMO(), XrdSys::IOEvents::Poller::parentPID, XrdSysSemaphore::Post(), XrdSys::IOEvents::Poller::TmoGet(), and XrdSysE2T().

Here is the call graph for this function:

◆ Exclude()

void XrdSys::IOEvents::PollPoll::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 264 of file XrdSysIOEventsPollPoll.icc.

266{
267 int ctnum;
268
269// Verify that this channel is assigned.
270//
271 ctnum = GetPollEnt(cP);
272 pollMutex.Lock();
273 if (chnlTab[ctnum] != cP) {pollMutex.UnLock(); return;}
274 pollMutex.UnLock();
275
276// If we are the poller thread then we can remove this now. Note that we will
277// still have the poll mutex because the caller would have it as well.
278// Otherwise, send a message to the poller to do this. We will need to release
279// the channel lock to prevent deadlocks. The caller will relock as needed.
280// This message always synchronizes with the poller.
281//
282 if (ISPOLLER)
283 {FDRem(ctnum);
284 return;
285 } else {
286 PipeData cmdbuff((char)PipeData::RmFD,0,(short)ctnum,cP->GetFD());
287 if (isLocked) {isLocked = false; UnLockChannel(cP);}
288 SendCmd(cmdbuff);
289 }
290}
#define ISPOLLER
int GetPollEnt(Channel *cP)
int SendCmd(PipeData &cmd)
void UnLockChannel(Channel *cP)

References XrdSys::IOEvents::Channel::GetFD(), XrdSys::IOEvents::Poller::GetPollEnt(), ISPOLLER, XrdSys::IOEvents::Poller::SendCmd(), and XrdSys::IOEvents::Poller::UnLockChannel().

Here is the call graph for this function:

◆ Include()

bool XrdSys::IOEvents::PollPoll::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 367 of file XrdSysIOEventsPollPoll.icc.

371{
372 static const int incVal = 256;
373 static const int cpSz = sizeof(Channel *);
374 static const int ptSz = sizeof(struct pollfd);
375 int fd, ctnum;
376
377// Validate the file descriptor
378//
379 fd = cP->GetFD();
380 if (fd & 0xffff0000)
381 {eNum = EBADF;
382 if (eTxt) *eTxt = "adding channel";
383 return false;
384 }
385
386// Make sure this channel is not already assigned to this poller
387//
388 if (GetPollEnt(cP))
389 {eNum = EEXIST;
390 if (eTxt) *eTxt = "adding channel";
391 return false;
392 }
393
394// Get the next channel table entry to be used
395//
396 pollMutex.Lock();
397 ctnum = 1;
398 while((ctnum < chnlMax) && (chnlTab[ctnum] != 0)) ctnum++;
399
400// Reallocate channel table if we don't have enough space. We also pre-allocate
401// a new poll table so that we can reflect failure to the caller as the poller
402// can't do that. The poller will swap the new one for the old one.
403//
404 if (ctnum >= chnlMax)
405 {Channel **cnewTab = (Channel **)realloc(chnlTab,(chnlMax+incVal)*cpSz);
406 if (pnewTab) free(pnewTab);
407 pnewTab = (struct pollfd *)malloc((chnlMax+incVal)*ptSz);
408 if (!cnewTab || !pnewTab)
409 {pollMutex.UnLock();
410 eNum = ENOMEM;
411 if (eTxt) *eTxt = "adding channel";
412 if (cnewTab) free(cnewTab);
413 if (pnewTab) free(pnewTab);
414 return false;
415 }
416 memset(&cnewTab[ctnum], 0, incVal*cpSz);
417 memset(&pnewTab[ctnum],-1, incVal*ptSz);
418 chnlTab = cnewTab; chnlMax += incVal; chnlNum = ctnum+1;
419 } else if (ctnum > chnlNum) chnlNum = ctnum;
420
421// Record the poll table entry in the channel
422//
423 chnlTab[ctnum] = cP;
424 SetPollEnt(cP, ctnum);
425 pollMutex.UnLock();
426
427// If we are the poller thread, then enable the poll entry in-line. Note that
428// we will still be holding the poll mutex because the caller also has it.
429// Otherwise, send a message to the poller to do this. We will need to release
430// the channel lock to prevent deadlocks. The caller will relock as needed.
431//
432 if (ISPOLLER)
433 {FDMod(ctnum, fd, cP->GetEvents());
434 return true;
435 } else {
436 PipeData cmdbuff((char)PipeData::MiFD, (char)cP->GetEvents(),
437 (short)ctnum, fd, 0);
438 if (isLocked) {isLocked = false; UnLockChannel(cP);}
439 SendCmd(cmdbuff);
440 }
441
442// All done
443//
444 return true;
445}
void SetPollEnt(Channel *cP, int ptEnt)

References XrdSys::IOEvents::Poller::Channel, XrdSys::IOEvents::Channel::GetEvents(), XrdSys::IOEvents::Channel::GetFD(), XrdSys::IOEvents::Poller::GetPollEnt(), ISPOLLER, XrdSys::IOEvents::Poller::SendCmd(), XrdSys::IOEvents::Poller::SetPollEnt(), and XrdSys::IOEvents::Poller::UnLockChannel().

Here is the call graph for this function:

◆ Modify()

bool XrdSys::IOEvents::PollPoll::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 451 of file XrdSysIOEventsPollPoll.icc.

455{
456
457// If we are the poller thread, then modify the poll entry in-line. Otherwise,
458// send a modification message to the poller. This requires that we unlock the
459// channel to prevent any deadlocks. The caller will relock it as needed.
460//
461 if (ISPOLLER)
462 {FDMod(GetPollEnt(cP), cP->GetFD(), cP->GetEvents());
463 return true;
464 } else {
465 PipeData cmdbuff((char)PipeData::MdFD, (char)cP->GetEvents(),
466 (short)GetPollEnt(cP), cP->GetFD(), 0);
467 if (isLocked) {isLocked = false; UnLockChannel(cP);}
468 SendCmd(cmdbuff);
469 }
470
471// All done
472//
473 return true;
474}

References XrdSys::IOEvents::Channel::GetEvents(), XrdSys::IOEvents::Channel::GetFD(), XrdSys::IOEvents::Poller::GetPollEnt(), ISPOLLER, XrdSys::IOEvents::Poller::SendCmd(), and XrdSys::IOEvents::Poller::UnLockChannel().

Here is the call graph for this function:

◆ Shutdown()

void XrdSys::IOEvents::PollPoll::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 513 of file XrdSysIOEventsPollPoll.icc.

514{
515 static XrdSysMutex shutMutex;
516
517// To avoid race conditions, we serialize this code
518//
519 shutMutex.Lock();
520
521// Release the appendages
522//
523 if (pollTab) {free(pollTab); pollTab = 0;}
524 if (pnewTab) {free(pnewTab); pnewTab = 0;}
525 if (chnlTab) {free(chnlTab); chnlTab = 0;}
526
527// All done
528//
529 shutMutex.UnLock();
530}

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

Here is the call graph for this function:

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