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

## Public Member Functions

| PollKQ (struct kevent *ptab, int numfd, int pfd, int pFD[2])
| ~PollKQ ()
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 ()

## Static Public Member Functions

static int | AllocMem (void **memP, int slots)
Static Public Member Functions inherited from XrdSys::IOEvents::Poller
static Poller * | Create (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
Channel * | attBase
bool | chDead
int | cmdFD
int | pipeBlen
char * | pipeBuff
struct pollfd | pipePoll
pthread_t | pollTid
PipeData | reqBuff
int | reqFD
Channel * | tmoBase
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 52 of file XrdSysIOEventsPollKQ.icc.

## Constructor & Destructor Documentation

## PollKQ()

XrdSys::IOEvents::PollKQ::PollKQ | ( | struct kevent * | ptab,
|  | int | numfd,
|  | int | pfd,
|  | int | pFD[2] )

inline

Definition at line 58 of file XrdSysIOEventsPollKQ.icc.

: Poller(pFD[0], pFD[1]), pollTab(ptab), cbNext(0),
pollDfd(pfd), pollMax(numfd), pollNum(1), numPoll(0)
{EV_SET(&armPipe, reqFD, EVFILT_READ,
EV_ADD|EV_CLEAR|EV_ENABLE, 0, 0, 0);
}
XrdSys::IOEvents::Poller::reqFD
int reqFD
Definition XrdSysIOEvents.hh:495
XrdSys::IOEvents::Poller::Poller
Poller(int cFD, int rFD)
Definition XrdSysIOEvents.cc:571

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

Here is the call graph for this function:

## ~PollKQ()

XrdSys::IOEvents::PollKQ::~PollKQ | ( |  | ) |

inline

Definition at line 64 of file XrdSysIOEventsPollKQ.icc.

{Stop();}
XrdSys::IOEvents::Poller::Stop
void Stop()
Definition XrdSysIOEvents.cc:1030

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

Here is the call graph for this function:

## Member Function Documentation

## AllocMem()

int XrdSys::IOEvents::PollKQ::AllocMem | ( | void ** | memP,
|  | int | slots )

static

Definition at line 156 of file XrdSysIOEventsPollKQ.icc.

{
int rc, bytes, alignment, pagsz = getpagesize();
// Calculate the size of the poll table and allocate it
//
bytes = slots * sizeof(struct kevent);
alignment = (bytes < pagsz ? 1024 : pagsz);
if (!(rc = posix_memalign(memP, alignment, bytes))) memset(*memP, 0, bytes);
return rc;
}

## Begin()

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

protected virtual

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 198 of file XrdSysIOEventsPollKQ.icc.

{
struct timespec *tmP, tmOut;
Channel *cP;
long long tmVal;
int numpolled, pollN;
// Indicate to the starting thread that all went well
//
retcode = 0;
*eTxt = 0;
syncsem->Post();
tmOut.tv_nsec = 0;
// Now start dispatching channels that are ready. We use the wakePend flag to
// keep the chatter down when we actually wakeup.
//
do {if ((tmVal = TmoGet()) < 0) tmP = 0;
else {tmOut.tv_sec = tmVal / 1000; tmP = &tmOut;}
do {numpolled = kevent(pollDfd, 0, 0, pollTab, pollMax, tmP);}
while (numpolled < 0 && errno == EINTR);
wakePend = true; numPoll = numpolled;
if (numpolled == 0) CbkTMO();
else if (numpolled < 0)
{int rc = errno;
//--------------------------------------------------------------
// If we are in a child process and the poll file descriptor
// has been closed, there is an immense chance the fork will be
// followed by an exec, in which case we don't want to abort
//--------------------------------------------------------------
if( rc == EBADF && parentPID != getpid() ) return;
std::cerr <<"KQ: " <<XrdSysE2T(rc) <<" polling for events" <<std::endl;
abort();
}
else for (int i = 0; i < numpolled; i++)
{if ((cP = (Channel *)pollTab[i].udata)) Dispatch(cP, i);
else if (!Process(i+1)) return;
}
pollN = AtomicGet(pollNum);
if (pollMax < pollN) AllocPT(pollN);
} while(1);
}
AtomicGet
#define AtomicGet(x)
Definition XrdSysAtomics.hh:71
XrdSysE2T
const char * XrdSysE2T(int errcode)
Definition XrdSysE2T.cc:104
XrdSys::IOEvents::Poller::TmoGet
int TmoGet()
Definition XrdSysIOEvents.cc:1180
XrdSys::IOEvents::Poller::CbkTMO
void CbkTMO()
Definition XrdSysIOEvents.cc:614
XrdSys::IOEvents::Poller::Channel
friend class Channel
Definition XrdSysIOEvents.hh:374
XrdSys::IOEvents::Poller::parentPID
static pid_t parentPID
Definition XrdSysIOEvents.hh:515

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

Here is the call graph for this function:

## Exclude()

void XrdSys::IOEvents::PollKQ::Exclude | ( | Channel * | cP,
|  | bool & | isLocked,
|  | bool | dover = 1 )

protected virtual

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 283 of file XrdSysIOEventsPollKQ.icc.

{
struct kevent chlist[2];
int i = 0, theFD = cP->GetFD(), kqStatus = GetPollEnt(cP);
// Setup the removal elements.
// may have been closed prior to this call (though this shouldn't happen).
//
if (kqStatus & rFilterX)
{EV_SET(&chlist[i], theFD, EVFILT_READ, EV_DELETE, 0, 0, cP);}
if (kqStatus & wFilterX)
{EV_SET(&chlist[i], theFD, EVFILT_WRITE, EV_DELETE, 0, 0, cP);}
// Remove this channel from the poll set. We ignore errors as the descriptor
// may have been closed prior to this call (though this shouldn't happen).
//
if (i) kevent(pollDfd, chlist, i, 0, 0, 0);
SetPollEnt(cP, 0);
AtomicDec(pollNum);
// If we need to verify this action, sync with the poller thread (note that the
// poller thread will not ask for this action unless it wants to deadlock). We
// may actually deadlock anyway if the channel lock is held. We are allowed to
// release it if the caller locked it. This will prevent a deadlock. Otherwise,
// if we are in a callback and this channel is not the one that initiated the
// exclude then we must make sure that we cancel any pending callback to the
// excluded channel as it may have been deleted and we won't know that here.
//
if (dover)
{PipeData cmdbuff;
if (isLocked)
{isLocked = false;
UnLockChannel(cP);
}
cmdbuff.req = PipeData::RmFD;
cmdbuff.fd = theFD;
SendCmd(cmdbuff);
} else {
if (cbNext)
for (int i = cbNext; i < numPoll; i++)
{if (cP == (Channel *)pollTab[i].udata)
pollTab[i].udata = &deadChP;
}
}
}
AtomicDec
#define AtomicDec(x)
Definition XrdSysAtomics.hh:68
XrdSys::IOEvents::Poller::GetPollEnt
int GetPollEnt(Channel *cP)
Definition XrdSysIOEvents.hh:438
XrdSys::IOEvents::Poller::SendCmd
int SendCmd(PipeData &cmd)
Definition XrdSysIOEvents.cc:993
XrdSys::IOEvents::Poller::UnLockChannel
void UnLockChannel(Channel *cP)
Definition XrdSysIOEvents.hh:448
XrdSys::IOEvents::Poller::SetPollEnt
void SetPollEnt(Channel *cP, int ptEnt)
Definition XrdSysIOEvents.cc:1021
XrdSys::IOEvents::Poller::PipeData
Definition XrdSysIOEvents.hh:496
XrdSys::IOEvents::Poller::PipeData::req
char req
Definition XrdSysIOEvents.hh:496

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

Here is the call graph for this function:

## Include()

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

protected virtual

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 334 of file XrdSysIOEventsPollKQ.icc.

{
// We simply call modify as this will add events to the kqueue as needed
//
if (!Modify(cP, eNum, eTxt, isLocked))
{if (eTxt) *eTxt = "adding channel";
return false;
}
// All went well. Bump the number in the set. The poller thread will
// reallocate the poll table if need be.
//
AtomicInc(pollNum);
return true;
}
AtomicInc
#define AtomicInc(x)
Definition XrdSysAtomics.hh:72
XrdSys::IOEvents::PollKQ::Modify
bool Modify(Channel *cP, int &eNum, const char **eTxt, bool &isLocked)
Definition XrdSysIOEventsPollKQ.icc:358

References AtomicInc, and Modify().

Here is the call graph for this function:

## Modify()

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

protected virtual

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 358 of file XrdSysIOEventsPollKQ.icc.

{
(void)isLocked;
struct kevent chlist[2];
int i = 0;
int events = cP->GetEvents(), theFD = cP->GetFD();
int kqStatus = GetPollEnt(cP);
// Establish new read event mask
//
if (events & Channel:: readEvents)
{if (!(kqStatus & rEnabled))
{EV_SET(&chlist[i], theFD, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, cP);
kqStatus |= rEnabled | rFilterX;
i++;
}
} else {
if (kqStatus & rEnabled)
{EV_SET(&chlist[i], theFD, EVFILT_READ, EV_DISABLE, 0, 0, cP);
kqStatus &= ~rEnabled;
i++;
}
}
// Establish new write event mask
//
if (events & Channel::writeEvents)
{if (!(kqStatus & wEnabled))
{EV_SET(&chlist[i], theFD, EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, cP);
kqStatus |= wEnabled | wFilterX;
i++;
}
} else {
if (kqStatus & wEnabled)
{EV_SET(&chlist[i], theFD, EVFILT_WRITE, EV_DISABLE, 0, 0, cP);
kqStatus &= ~wEnabled;
i++;
}
}
// Modify this fd if anything changed
//
if (i)
{if (kevent(pollDfd, chlist, i, 0, 0, 0) < 0)
{eNum = errno;
if (eTxt) *eTxt = "modifying poll events";
return false;
}
SetPollEnt(cP, kqStatus);
}
// All done
//
return true;
}
XrdSys::IOEvents::Channel::writeEvents
@ writeEvents
Write and Write Timeouts.
Definition XrdSysIOEvents.hh:193
XrdSys::IOEvents::Channel::readEvents
@ readEvents
Read and Read Timeouts.
Definition XrdSysIOEvents.hh:192

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

Referenced by Include().

Here is the call graph for this function:
Here is the caller graph for this function:

## Shutdown()

void XrdSys::IOEvents::PollKQ::Shutdown | ( |  | ) |

protected virtual

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 455 of file XrdSysIOEventsPollKQ.icc.

{
static XrdSysMutex shutMutex;
// To avoid race conditions, we serialize this code
//
shutMutex.Lock();
// Release the poll table
//
if (pollTab) {free(pollTab); pollTab = 0;}
// Close the kqueue file descriptor
//
if (pollDfd >= 0) {close(pollDfd); pollDfd = -1;}
// All done
//
shutMutex.UnLock();
}
close
#define close(a)
Definition XrdPosix.hh:48
XrdSysMutex::Lock
void Lock()
Definition XrdSysPthread.hh:222
XrdSysMutex::UnLock
void UnLock()
Definition XrdSysPthread.hh:224

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:

- XrdSysIOEventsPollKQ.icc