Loading...
Searching...
No Matches
XrdSys::IOEvents::Channel Class Reference

`#include <XrdSysIOEvents.hh>`

Collaboration diagram for XrdSys::IOEvents::Channel:

## Public Types

enum | EventCode { readEvents = 0x01 , writeEvents = 0x04 , rwEvents = 0x05 , errorEvents = 0x10 , stopEvent = 0x20 , allEvents = 0x35 }
| Event bits used to feed Enable() and Disable(); can be or'd. More...

## Public Member Functions

| Channel (Poller *pollP, int fd, CallBack *cbP=0, void *cbArg=0)
void | Delete ()
bool | Disable (int events, const char **eText=0)
bool | Enable (int events, int timeout=0, const char **eText=0)
void | GetCallBack (CallBack **cbP, void **cbArg)
int | GetEvents ()
int | GetFD ()
void | SetCallBack (CallBack *cbP, void *cbArg=0)
void | SetFD (int fd)

## Friends

class | Poller

## Detailed Description

Definition at line 173 of file XrdSysIOEvents.hh.

## Member Enumeration Documentation

## EventCode

enum XrdSys::IOEvents::Channel::EventCode

Event bits used to feed Enable() and Disable(); can be or'd.

Enumerator
readEvents | Read and Read Timeouts.
writeEvents | Write and Write Timeouts.
rwEvents | Both of the above.
errorEvents | Error event non-r/w specific.
stopEvent | Poller stop event.
allEvents | All of the above.

Definition at line 192 of file XrdSysIOEvents.hh.

{readEvents = 0x01,
writeEvents = 0x04,
rwEvents = 0x05,
errorEvents = 0x10,
stopEvent = 0x20,
allEvents = 0x35
};
XrdSys::IOEvents::Channel::allEvents
@ allEvents
All of the above.
Definition XrdSysIOEvents.hh:197
XrdSys::IOEvents::Channel::errorEvents
@ errorEvents
Error event non-r/w specific.
Definition XrdSysIOEvents.hh:195
XrdSys::IOEvents::Channel::stopEvent
@ stopEvent
Poller stop event.
Definition XrdSysIOEvents.hh:196
XrdSys::IOEvents::Channel::writeEvents
@ writeEvents
Write and Write Timeouts.
Definition XrdSysIOEvents.hh:193
XrdSys::IOEvents::Channel::rwEvents
@ rwEvents
Both of the above.
Definition XrdSysIOEvents.hh:194
XrdSys::IOEvents::Channel::readEvents
@ readEvents
Read and Read Timeouts.
Definition XrdSysIOEvents.hh:192

## Constructor & Destructor Documentation

## Channel()

XrdSys::IOEvents::Channel::Channel | ( | Poller * | pollP,
|  | int | fd,
|  | CallBack * | cbP = 0,
|  | void * | cbArg = 0 )

Constructor.

Parameters

  pollP | Pointer to the poller object to which this channel will be assigned. Events are initially disabled after assignment and no timeout applies. Poller object assignment is permanent for the life of the channel object.
  fd | The associated file descriptor number. It should not be assigned to any other channel and must be valid when the channel is enabled. Use SetFD() to set a new value.
  cbP | Pointer to the callback object (see above). The callback object must not be deleted while associated to a channel. A callback object must exist in order for the channel to be enabled. Use SetCallBack() if you deferred setting it here.
  cbArg | The argument to be passed to the callback object.

Definition at line 285 of file XrdSysIOEvents.cc.

: chPollXQ(pollP), chCB(cbP), chCBA(cbArg)
{
attList.next = attList.prev = this;
tmoList.next = tmoList.prev = this;
inTOQ = 0;
pollEnt = 0;
chStat = isClear;
Reset(&pollInit, fd);
pollP->Attach(this);
}
XrdSys::IOEvents::pollInit
PollerInit pollInit
Definition XrdSysIOEvents.cc:273

References Poller, and XrdSys::IOEvents::pollInit.

Here is the call graph for this function:

## Member Function Documentation

## Delete()

void XrdSys::IOEvents::Channel::Delete | ( |  | ) |

Delete a channel. You must use this method instead of delete. The Delete() may block if an channel is being deleted outside of the poller thread. When this object is deleted, all events are disabled, pending callbacks are either completed or canceled, and the channel is removed from the assigned poller. Only then is the storage freed.

Definition at line 303 of file XrdSysIOEvents.cc.

{
Poller *myPoller;
bool isLocked = true;
// Do some tracing
//
IF_TRACE(Delete,chFD,"status="<<STATUS);
// Lock ourselves during the delete process. If the channel is disassociated
// or the real poller is set to the error poller then this channel is clean
// and can be deleted (i.e. the channel ran through Detach()).
//
chMutex.Lock();
if (!chPollXQ || chPollXQ == &pollErr1)
{chMutex.UnLock();
delete this;
return;
}
// Disable and remove ourselves from all queues
//
myPoller = chPollXQ;
chPollXQ->Detach(this,isLocked,false);
if (!isLocked) chMutex.Lock();
// If we are in callback mode then we will need to delay the destruction until
// after the callback completes unless this is the poller thread. In that case,
// we need to tell the poller that we have been destroyed in a shelf-stable way.
//
if (chStat)
{if (XrdSysThread::Same(XrdSysThread::ID(),myPoller->pollTid))
{myPoller->chDead = true;
chMutex.UnLock();
} else {
XrdSysSemaphore cbDone(0);
IF_TRACE(Delete,chFD,"waiting for callback");
chStat = isDead;
chCBA = (void *)&cbDone;
chMutex.UnLock();
cbDone.Wait();
}
}
// It is now safe to release the storage
//
IF_TRACE(Delete,chFD,"chan="<< std::hex<<(void *)this<< std::dec);
delete this;
}
IF_TRACE
#define IF_TRACE(x, fd, y)
Definition XrdSysIOEvents.cc:93
STATUS
#define STATUS
Definition XrdSysIOEvents.cc:57
XrdSysThread::Same
static int Same(pthread_t t1, pthread_t t2)
Definition XrdSysPthread.hh:593
XrdSysThread::ID
static pthread_t ID(void)
Definition XrdSysPthread.hh:584
XrdSys::IOEvents::Channel::Delete
void Delete()
Definition XrdSysIOEvents.cc:303
XrdSys::IOEvents::Channel::Poller
friend class Poller
Definition XrdSysIOEvents.hh:175
XrdSys::IOEvents::pollErr1
PollerErr1 pollErr1
Definition XrdSysIOEvents.cc:272

References XrdSys::IOEvents::Poller::chDead, Delete(), XrdSysThread::ID(), IF_TRACE, Poller, XrdSys::IOEvents::pollErr1, XrdSys::IOEvents::Poller::pollTid, XrdSysThread::Same(), STATUS, and XrdSysSemaphore::Wait().

Referenced by Delete(), XrdCl::PollerBuiltIn::Finalize(), XrdCl::PollerBuiltIn::RemoveSocket(), and XrdCl::PollerBuiltIn::Stop().

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

## Disable()

bool XrdSys::IOEvents::Channel::Disable | ( | int | events,
|  | const char ** | eText = 0 )

Disable one or more events. Ignored for already disabled events.

Parameters

  events | one or more events or'd together (see EventCode above).
  eText | optional pointer to where an operation description is to be placed when an error occurs (i.e. returns false).

Returns
  true Events successfully disabled. false Events not disabled; errno holds the error number and if eText is supplied, points to the operation desscription.

Definition at line 356 of file XrdSysIOEvents.cc.

{
int eNum = 0, newev, curev;
bool retval = true, isLocked = true;
// Lock this channel
//
chMutex.Lock();
// Get correct current events; depending on the state of the channel
//
if (chPoller == &pollWait) curev = static_cast<int>(reMod);
else curev = static_cast<int>(chEvents);
// Trace this entry
//
IF_TRACE(Disable,chFD,"->Disable(" <<events <<") chev=" <<curev);
// Calculate new event mask
//
events &= allEvents;
newev = curev & ~events;
// If something has changed, then modify the event mask in the poller. The
// poller may or may not unlock this channel during the process.
//
if (newev != curev)
{chEvents = newev;
retval = chPoller->Modify(this, eNum, eText, isLocked);
TRACE_MOD(Disable,chFD,newev);
} else {
TRACE_NOD(Disable,chFD,newev);
}
if (isLocked) chMutex.UnLock();
// All done
//
if (!retval) errno = eNum;
return retval;
}
TRACE_NOD
#define TRACE_NOD(x, fd, y)
Definition XrdSysIOEvents.cc:101
TRACE_MOD
#define TRACE_MOD(x, fd, y)
Definition XrdSysIOEvents.cc:97
XrdSys::IOEvents::Channel::Disable
bool Disable(int events, const char **eText=0)
Definition XrdSysIOEvents.cc:356
XrdSys::IOEvents::pollWait
PollerWait pollWait
Definition XrdSysIOEvents.cc:274

References allEvents, Disable(), IF_TRACE, XrdSys::IOEvents::pollWait, TRACE_MOD, and TRACE_NOD.

Referenced by Disable(), XrdCl::PollerBuiltIn::EnableReadNotification(), XrdCl::PollerBuiltIn::EnableWriteNotification(), XrdCl::PollerBuiltIn::RemoveSocket(), and XrdCl::PollerBuiltIn::Stop().

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

## Enable()

bool XrdSys::IOEvents::Channel::Enable | ( | int | events,
|  | int | timeout = 0,
|  | const char ** | eText = 0 )

Enable one or more events. Events that are already enabled remain enabled but may have their timeout value change.

Enable can fail for many reasons. Most importantly, if the channel was disabled for all events when a fatal error occurred; enabling it immediately returns the fatal error without invoking the callback. This happens on platforms that disallow physically masking out error events.

Additionally, when an error occurs and the channel is not enabled for error events but is enabled for read or write, the callback is called indicating ReadyToRead or ReadyToWrite. A subsequent write will then end with an error (typically, EPIPE) and a subsequent read will end with an erorr or indicate zero bytes read; either of which should be treated as an error (typically, POLLHUP). Generally, you should always allow separable error events.

Parameters

  events | one or more events or'd together (see EventCode above).

  timeout

  >0 maximum seconds that may elapsed before a timeout event corresponding to the specified event(s) occurs. =0 Keep whatever timeout is currently in effect from the previous Enable() invocation for the event(s). <0 No timeout applies. There can be separate timeouts for read and write if Enable() is separately called for each event code. Otherwise, the timeout applies to all specified events. The timeout is ignored for error events.

  eText | optional pointer to where an operation description is to be placed when an error occurs (i.e. returns false).

Returns
  true Events successfully enabled. false Events not enabled; errno holds the error number and if eText is supplied, points to the operation desscription.

Definition at line 401 of file XrdSysIOEvents.cc.

{
int eNum = 0, newev, curev, tmoSet = 0;
bool retval, setTO, isLocked = true;
// Lock ourselves against any changes (this is a recursive mutex)
//
chMutex.Lock();
// Get correct current events; depending on the state of the channel
//
if (chPoller == &pollWait) curev = static_cast<int>(reMod);
else curev = static_cast<int>(chEvents);
// Trace this entry
//
IF_TRACE(Enable,chFD,"->Enable("<<events<<','<<timeout<<") chev="<<curev);
// Establish events that should be enabled
//
events &= allEvents;
newev = (curev ^ events) & events;
chEvents = curev | events;
// Handle timeout changes now
//
if (REVENTS(events))
{ if (timeout > 0) chRTO = timeout;
else if (timeout < 0) chRTO = 0;
if (rdDL != Poller::maxTime || chRTO) tmoSet |= CallBack::ReadyToRead;
}
if (WEVENTS(events))
{ if (timeout > 0) chWTO = timeout;
else if (timeout < 0) chWTO = 0;
if (wrDL != Poller::maxTime || chWTO) tmoSet |= CallBack::ReadyToWrite;
}
// Check if we have to reset the timeout. We need to hold the channel lock here.
//
if (tmoSet && chPoller != &pollErr1)
setTO = chPollXQ->TmoAdd(this, tmoSet);
else setTO = false;
// Check if any modifcations needed here. If so, invoke the modifier. Note that
// the modify will unlock the channel if the operation causes a wait. So,
// we cannot depend on the channel being locked upon return. The reason we do
// not unlock here is because we must ensure the channel doesn't change while
// we call modify. We let modify determine what to do.
//
if (newev)
{retval = chPoller->Modify(this, eNum, eText, isLocked);
TRACE_MOD(Enable,chFD,(curev | events));
} else {
retval = true;
TRACE_NOD(Enable,chFD,(curev | events));
}
// We need to notify the poller thread if the added deadline is the first in the
// queue and the poller is waiting. We also optimize for the case where the
// poller thread is always woken up to perform an action in which case it
// doesn't need a separate wakeup. We only do this if the enable succeeed. Note
// that we cannot hold the channel mutex for this call because it may wait.
//
if (isLocked) chMutex.UnLock();
bool isWakePend = CPP_ATOMIC_LOAD(chPollXQ->wakePend, std::memory_order_consume);
if (retval && !isWakePend && setTO && isLocked) chPollXQ->WakeUp();
// All done
//
if (!retval) errno = eNum;
return retval;
}
CPP_ATOMIC_LOAD
#define CPP_ATOMIC_LOAD(x, order)
Definition XrdSysAtomics.hh:95
REVENTS
#define REVENTS(x)
Definition XrdSysIOEvents.cc:78
WEVENTS
#define WEVENTS(x)
Definition XrdSysIOEvents.cc:80
XrdSys::IOEvents::CallBack::ReadyToWrite
@ ReadyToWrite
Writing won't block.
Definition XrdSysIOEvents.hh:90
XrdSys::IOEvents::CallBack::ReadyToRead
@ ReadyToRead
New data has arrived.
Definition XrdSysIOEvents.hh:88
XrdSys::IOEvents::Channel::Enable
bool Enable(int events, int timeout=0, const char **eText=0)
Definition XrdSysIOEvents.cc:401
XrdSys::IOEvents::Poller::maxTime
static time_t maxTime
Definition XrdSysIOEvents.hh:513

References allEvents, CPP_ATOMIC_LOAD, Enable(), IF_TRACE, XrdSys::IOEvents::Poller::maxTime, XrdSys::IOEvents::pollErr1, XrdSys::IOEvents::pollWait, XrdSys::IOEvents::CallBack::ReadyToRead, XrdSys::IOEvents::CallBack::ReadyToWrite, REVENTS, TRACE_MOD, TRACE_NOD, and WEVENTS.

Referenced by Enable(), XrdCl::PollerBuiltIn::EnableReadNotification(), XrdCl::PollerBuiltIn::EnableWriteNotification(), and XrdCl::PollerBuiltIn::Start().

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

## GetCallBack()

void XrdSys::IOEvents::Channel::GetCallBack | ( | CallBack ** | cbP,
|  | void ** | cbArg )

Get the callback object and argument associated with this channel.

Parameters

  cbP | Place where the pointer is to be returned.
  cbArg | Place where the callback argument is to be returned.

Definition at line 480 of file XrdSysIOEvents.cc.

{
chMutex.Lock();
*cbP = chCB;
*cbArg = chCBA;
chMutex.UnLock();
}

## GetEvents()

int XrdSys::IOEvents::Channel::GetEvents | ( |  | ) |

inline

Get the events that are currently enabled for this channel.

Returns
  >0 Event bits that are enabled (see EventCode above). =0 No events are enabled. <0 Channel not assigned to a Poller object.

Definition at line 267 of file XrdSysIOEvents.hh.

{return (chPoller ? static_cast<int>(chEvents) : -1);}

Referenced by XrdSys::IOEvents::PollE::Include(), XrdSys::IOEvents::PollPoll::Include(), XrdSys::IOEvents::PollPort::Include(), XrdSys::IOEvents::PollE::Modify(), XrdSys::IOEvents::PollKQ::Modify(), XrdSys::IOEvents::PollPoll::Modify(), and XrdSys::IOEvents::PollPort::Modify().

Here is the caller graph for this function:

## GetFD()

int XrdSys::IOEvents::Channel::GetFD | ( |  | ) |

inline

Get the file descriptor number associated with this channel.

Returns
  >=0 The file descriptor number. < 0 No file desciptor associated with the channel.

Definition at line 276 of file XrdSysIOEvents.hh.

{return chFD;}

Referenced by XrdSys::IOEvents::PollE::Exclude(), XrdSys::IOEvents::PollKQ::Exclude(), XrdSys::IOEvents::PollPoll::Exclude(), XrdSys::IOEvents::PollPort::Exclude(), XrdSys::IOEvents::PollE::Include(), XrdSys::IOEvents::PollPoll::Include(), XrdSys::IOEvents::PollPort::Include(), XrdSys::IOEvents::PollE::Modify(), XrdSys::IOEvents::PollerInit::Modify(), XrdSys::IOEvents::PollKQ::Modify(), XrdSys::IOEvents::PollPoll::Modify(), and XrdSys::IOEvents::PollPort::Modify().

Here is the caller graph for this function:

## SetCallBack()

void XrdSys::IOEvents::Channel::SetCallBack | ( | CallBack * | cbP,
|  | void * | cbArg = 0 )

Set the callback object and argument associated with this channel.

Parameters

  cbP | Pointer to the callback object (see above). The callback object must not be deleted while associated to a channel. A null callback object pointer effectively disables the channel.
  cbArg | The argument to be passed to the callback object.

Definition at line 513 of file XrdSysIOEvents.cc.

{
// We only need to have the channel lock to set the callback. If the object
// is in the process of being destroyed, we do nothing.
//
chMutex.Lock();
if (chStat != isDead)
{chCB = cbP;
chCBA = cbArg;
}
chMutex.UnLock();
}

## SetFD()

void XrdSys::IOEvents::Channel::SetFD | ( | int | fd | ) |

Set a new file descriptor to be associated with this channel. The channel is removed from polling consideration but remains attached to the poller. The new file descriptor is recorded but the channel remains disabled. You must use Enable() to add the file descriptor back to the polling set. This allows you to retract a file descriptor about to be closed without having a new file descriptor handy (e.g., use -1). This facilitates channel re-use.

Parameters

  fd | The associated file descriptor number.

Definition at line 531 of file XrdSysIOEvents.cc.

{
bool isLocked = true;
// Obtain the channel lock. If the object is in callback mode we have some
// extra work to do. If normal callback then indicate the channel transitioned
// to prevent it being automatically re-enabled. If it's being destroyed, then
// do nothing. Otherwise, this is a stupid double setFD call.
//
chMutex.Lock();
if (chStat == isDead)
{chMutex.UnLock();
return;
}
// This is a tricky deal here because we need to protect ourselves from other
// threads as well as the poller trying to do a callback. We first, set the
// poller target. This means the channel is no longer ready and callbacks will
// be skipped. We then remove the current file descriptor. This may unlock the
// channel but at this point that's ok.
//
if (inPSet)
{chPoller = &pollWait;
chPollXQ->Detach(this, isLocked, true);
if (!isLocked) chMutex.Lock();
}
// Indicate channel needs to be re-enabled then unlock the channel
//
Reset(&pollInit, fd);
chMutex.UnLock();
}

References XrdSys::IOEvents::pollInit, and XrdSys::IOEvents::pollWait.

## Friends And Related Symbol Documentation

## Poller

friend class Poller

friend

Definition at line 175 of file XrdSysIOEvents.hh.

References Poller.

Referenced by Channel(), Delete(), and Poller.

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

- XrdSysIOEvents.hh
- XrdSysIOEvents.cc