XRootD
XrdPoll Class Referenceabstract

#include <XrdPoll.hh>

+ Inheritance diagram for XrdPoll:
+ Collaboration diagram for XrdPoll:

Classes

struct  PipeData
 
union  PipeData.Parms
 
struct  PipeData.Parms.Arg
 

Public Member Functions

 XrdPoll ()
 
virtual ~XrdPoll ()
 
virtual void Disable (XrdPollInfo &pInfo, const char *etxt=0)=0
 
virtual int Enable (XrdPollInfo &pInfo)=0
 
virtual void Start (XrdSysSemaphore *syncp, int &rc)=0
 

Static Public Member Functions

static int Attach (XrdPollInfo &pInfo)
 
static void Detach (XrdPollInfo &pInfo)
 
static int Finish (XrdPollInfo &pInfo, const char *etxt=0)
 
static char * Poll2Text (short events)
 
static int Setup (int numfd)
 
static int Stats (char *buff, int blen, int do_sync=0)
 

Public Attributes

int PID
 
pthread_t TID
 

Static Public Attributes

static XrdPollPollers [XRD_NUMPOLLERS] = {0, 0, 0}
 

Protected Member Functions

virtual void Exclude (XrdPollInfo &pInfo)=0
 
int getRequest ()
 
virtual int Include (XrdPollInfo &pInfo)=0
 

Static Protected Member Functions

static XrdPollnewPoller (int pollid, int numfd)
 

Protected Attributes

int CmdFD
 
int numEnabled
 
int numEvents
 
int numInterrupts
 
int PipeBlen
 
char * PipeBuff
 
struct pollfd PipePoll
 
XrdSysMutex PollPipe
 
PipeData ReqBuff
 
int ReqFD
 

Static Protected Attributes

static const char * TraceID = "Poll"
 

Detailed Description

Definition at line 40 of file XrdPoll.hh.


Class Documentation

◆ XrdPoll::PipeData.Parms

union XrdPoll::PipeData.Parms

Definition at line 119 of file XrdPoll.hh.

+ Collaboration diagram for XrdPoll::PipeData.Parms:
Class Members
Parms Arg
XrdSysSemaphore * theSem

◆ XrdPoll::PipeData.Parms.Arg

struct XrdPoll::PipeData.Parms.Arg

Definition at line 120 of file XrdPoll.hh.

+ Collaboration diagram for XrdPoll::PipeData.Parms.Arg:
Class Members
int ent
int fd

Constructor & Destructor Documentation

◆ XrdPoll()

XrdPoll::XrdPoll ( )

Definition at line 118 of file XrdPoll.cc.

119 {
120  int fildes[2];
121 
122  TID=0;
123  numAttached=numEnabled=numEvents=numInterrupts=0;
124 
125  if (XrdSysFD_Pipe(fildes) == 0)
126  {CmdFD = fildes[1];
127  ReqFD = fildes[0];
128  } else {
129  CmdFD = ReqFD = -1;
130  Log.Emsg("Poll", errno, "create poll pipe");
131  }
132  PipeBuff = 0;
133  PipeBlen = 0;
134  PipePoll.fd = ReqFD;
135  PipePoll.events = POLLIN | POLLRDNORM;
136 }
int numInterrupts
Definition: XrdPoll.hh:134
pthread_t TID
Definition: XrdPoll.hh:83
struct pollfd PipePoll
Definition: XrdPoll.hh:116
int ReqFD
Definition: XrdPoll.hh:118
int PipeBlen
Definition: XrdPoll.hh:128
int numEvents
Definition: XrdPoll.hh:133
char * PipeBuff
Definition: XrdPoll.hh:127
int numEnabled
Definition: XrdPoll.hh:132
int CmdFD
Definition: XrdPoll.hh:117
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
XrdSysError Log
Definition: XrdConfig.cc:112

References XrdSysError::Emsg(), and XrdGlobal::Log.

+ Here is the call graph for this function:

◆ ~XrdPoll()

virtual XrdPoll::~XrdPoll ( )
inlinevirtual

Definition at line 90 of file XrdPoll.hh.

90 {}

Member Function Documentation

◆ Attach()

int XrdPoll::Attach ( XrdPollInfo pInfo)
static

Definition at line 144 of file XrdPoll.cc.

145 {
146  int i;
147  XrdPoll *pp;
148 
149 // We allow only one attach at a time to simplify the processing
150 //
151  doingAttach.Lock();
152 
153 // Find a poller with the smallest number of entries
154 //
155  pp = Pollers[0];
156  for (i = 1; i < XRD_NUMPOLLERS; i++)
157  if (pp->numAttached > Pollers[i]->numAttached) pp = Pollers[i];
158 
159 // Include this FD into the poll set of the poller
160 //
161  if (!pp->Include(pInfo)) {doingAttach.UnLock(); return 0;}
162 
163 // Complete the link setup
164 //
165  pInfo.Poller = pp;
166  pp->numAttached++;
167  doingAttach.UnLock();
168  TRACEI(POLL, "FD " <<pInfo.FD <<" attached to poller " <<pp->PID
169  <<"; num=" <<pp->numAttached);
170  return 1;
171 }
#define XRD_NUMPOLLERS
Definition: XrdPoll.hh:35
#define TRACEI(act, x)
Definition: XrdTrace.hh:66
XrdPoll * Poller
Definition: XrdPollInfo.hh:43
static XrdPoll * Pollers[XRD_NUMPOLLERS]
Definition: XrdPoll.hh:87
int PID
Definition: XrdPoll.hh:82
virtual int Include(XrdPollInfo &pInfo)=0

References XrdPollInfo::FD, Include(), PID, XrdPollInfo::Poller, TRACEI, and XRD_NUMPOLLERS.

Referenced by XrdLink::Activate().

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

◆ Detach()

void XrdPoll::Detach ( XrdPollInfo pInfo)
static

Definition at line 177 of file XrdPoll.cc.

178 {
179  XrdPoll *pp;
180 
181 // If link is not attached, simply return
182 //
183  if (!(pp = pInfo.Poller)) return;
184 
185 // Exclude this link from the associated poll set
186 //
187  pp->Exclude(pInfo);
188 
189 // Make sure we are consistent
190 //
191  doingAttach.Lock();
192  if (!pp->numAttached)
193  {Log.Emsg("Poll","Underflow detaching", pInfo.Link.ID); abort();}
194  pp->numAttached--;
195  doingAttach.UnLock();
196  TRACEI(POLL, "FD " <<pInfo.FD <<" detached from poller " <<pp->PID
197  <<"; num=" <<pp->numAttached);
198 }
XrdLink & Link
Definition: XrdPollInfo.hh:41
virtual void Exclude(XrdPollInfo &pInfo)=0

References XrdSysError::Emsg(), Exclude(), XrdPollInfo::FD, XrdLink::ID, XrdPollInfo::Link, XrdGlobal::Log, PID, XrdPollInfo::Poller, and TRACEI.

Referenced by XrdLinkXeq::Close().

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

◆ Disable()

virtual void XrdPoll::Disable ( XrdPollInfo pInfo,
const char *  etxt = 0 
)
pure virtual

Implemented in XrdPollPoll, and XrdPollE.

Referenced by XrdLinkCtl::idleScan(), and XrdLink::Terminate().

+ Here is the caller graph for this function:

◆ Enable()

virtual int XrdPoll::Enable ( XrdPollInfo pInfo)
pure virtual

Implemented in XrdPollPoll, and XrdPollE.

Referenced by XrdLinkXeq::DoIt(), and XrdLink::Enable().

+ Here is the caller graph for this function:

◆ Exclude()

virtual void XrdPoll::Exclude ( XrdPollInfo pInfo)
protectedpure virtual

Implemented in XrdPollPoll, and XrdPollE.

Referenced by Detach().

+ Here is the caller graph for this function:

◆ Finish()

int XrdPoll::Finish ( XrdPollInfo pInfo,
const char *  etxt = 0 
)
static

Definition at line 204 of file XrdPoll.cc.

205 {
206  static XrdPoll_End LinkEnd;
207 
208 // If this link is already scheduled for termination, ignore this call.
209 //
210  if (pInfo.Link.getProtocol() == &LinkEnd)
211  {TRACEI(POLL, "Link " <<pInfo.FD <<" already terminating; "
212  <<(etxt ? etxt : "") <<" request ignored.");
213  return 0;
214  }
215 
216 // Set the protocol pointer to be link termination
217 //
218  pInfo.Link.setProtocol(&LinkEnd, false, true);
219  if (!etxt) etxt = "reason unknown";
220  pInfo.Link.setEtext(etxt);
221  TRACEI(POLL, "Link " <<pInfo.FD <<" terminating: " <<etxt);
222  return 1;
223 }

References XrdPollInfo::FD, XrdLink::getProtocol(), XrdPollInfo::Link, XrdLink::setEtext(), XrdLink::setProtocol(), and TRACEI.

Referenced by XrdPollE::Disable(), XrdPollPoll::Disable(), XrdPollE::Start(), and XrdPollPoll::Start().

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

◆ getRequest()

int XrdPoll::getRequest ( )
protected

Definition at line 232 of file XrdPoll.cc.

233 {
234  ssize_t rlen;
235  int rc;
236 
237 // See if we are to resume a read or start a fresh one
238 //
239  if (!PipeBlen)
240  {PipeBuff = (char *)&ReqBuff; PipeBlen = sizeof(ReqBuff);}
241 
242 // Wait for the next request. Some OS's (like Linux) don't support non-blocking
243 // pipes. So, we must front the read with a poll.
244 //
245  do {rc = poll(&PipePoll, 1, 0);}
246  while(rc < 0 && (errno == EAGAIN || errno == EINTR));
247  if (rc < 1) return 0;
248 
249 // Now we can put up a read without a delay. Normally a full command will be
250 // present. Under some heavy conditions, this may not be the case.
251 //
252  do {rlen = read(ReqFD, PipeBuff, PipeBlen);}
253  while(rlen < 0 && errno == EINTR);
254  if (rlen <= 0)
255  {if (rlen) Log.Emsg("Poll", errno, "read from request pipe");
256  return 0;
257  }
258 
259 // Check if all the data has arrived. If not all the data is present, defer
260 // this request until more data arrives.
261 //
262  if (!(PipeBlen -= rlen)) return 1;
263  PipeBuff += rlen;
264  TRACE(POLL, "Poller " <<PID <<" still needs " <<PipeBlen <<" req pipe bytes");
265  return 0;
266 }
ssize_t read(int fildes, void *buf, size_t nbyte)
#define TRACE(act, x)
Definition: XrdTrace.hh:63
PipeData ReqBuff
Definition: XrdPoll.hh:126

References XrdSysError::Emsg(), XrdGlobal::Log, read(), and TRACE.

+ Here is the call graph for this function:

◆ Include()

virtual int XrdPoll::Include ( XrdPollInfo pInfo)
protectedpure virtual

Implemented in XrdPollPoll, and XrdPollE.

Referenced by Attach().

+ Here is the caller graph for this function:

◆ newPoller()

XrdPoll * XrdPoll::newPoller ( int  pollid,
int  numfd 
)
staticprotected

Definition at line 45 of file XrdPollE.icc.

46 {
47  int pfd, wfd, bytes, alignment, pagsz = getpagesize();
48  struct epoll_event *pp;
49 
50 // Open the /dev/poll driver
51 //
52 #ifndef EPOLL_CLOEXEC
53  if ((pfd = epoll_create(maxfd)) >= 0) fcntl(pfd, F_SETFD, FD_CLOEXEC);
54  else
55 #else
56  if ((pfd = epoll_create1(EPOLL_CLOEXEC)) < 0)
57 #endif
58  {Log.Emsg("Poll", errno, "create epoll device"); return 0;}
59 
60  if ((wfd = eventfd(0, EFD_CLOEXEC)) < 0)
61  {Log.Emsg("Poll", errno,
62  "create an eventfd as the wait-poller descriptor");
63  close(pfd);
64  return 0;
65  }
66 
67 // Calculate the size of the poll table and allocate it
68 //
69  bytes = maxfd * sizeof(struct epoll_event);
70  alignment = (bytes < pagsz ? 1024 : pagsz);
71  if (posix_memalign((void **)&pp, alignment, bytes))
72  {Log.Emsg("Poll", ENOMEM, "create poll table");
73  close(wfd);
74  close(pfd);
75  return 0;
76  }
77 
78 // Create new poll object
79 //
80  memset((void *)pp, 0, bytes);
81  return (XrdPoll *)new XrdPollE(pp, maxfd, pfd, wfd);
82 }
int fcntl(int fd, int cmd,...)
#define close(a)
Definition: XrdPosix.hh:43

References close, XrdSysError::Emsg(), fcntl(), and XrdGlobal::Log.

+ Here is the call graph for this function:

◆ Poll2Text()

char * XrdPoll::Poll2Text ( short  events)
static

Definition at line 272 of file XrdPoll.cc.

273 {
274  if (events & POLLERR) return strdup("socket error");
275 
276  if (events & POLLHUP) return strdup("hangup");
277 
278  if (events & POLLNVAL) return strdup("socket closed");
279 
280  {char buff[64];
281  sprintf(buff, "unusual event (%.4x)", events);
282  return strdup(buff);
283  }
284  return (char *)0;
285 }

Referenced by XrdLinkXeq::Peek(), XrdLinkXeq::Recv(), XrdLinkXeq::RecvAll(), XrdPollPoll::Start(), and XrdLink::Wait4Data().

+ Here is the caller graph for this function:

◆ Setup()

int XrdPoll::Setup ( int  numfd)
static

Definition at line 291 of file XrdPoll.cc.

292 {
293  pthread_t tid;
294  int maxfd, retc, i;
295  struct XrdPollArg PArg;
296 
297 // Calculate the number of table entries per poller
298 //
299  maxfd = (numfd / XRD_NUMPOLLERS) + 16;
300 
301 // Verify that we initialized the poller table
302 //
303  for (i = 0; i < XRD_NUMPOLLERS; i++)
304  {if (!(Pollers[i] = newPoller(i, maxfd))) return 0;
305  Pollers[i]->PID = i;
306 
307  // Now start a thread to handle this poller object
308  //
309  PArg.Poller = Pollers[i];
310  PArg.retcode= 0;
311  TRACE(POLL, "Starting poller " <<i);
312  if ((retc = XrdSysThread::Run(&tid,XrdStartPolling,(void *)&PArg,
313  XRDSYSTHREAD_BIND, "Poller")))
314  {Log.Emsg("Poll", retc, "create poller thread"); return 0;}
315  Pollers[i]->TID = tid;
316  PArg.PollSync.Wait();
317  if (PArg.retcode)
318  {Log.Emsg("Poll", PArg.retcode, "start poller");
319  return 0;
320  }
321  }
322 
323 // All done
324 //
325  return 1;
326 }
void * XrdStartPolling(void *parg)
Definition: XrdPoll.cc:107
#define XRDSYSTHREAD_BIND
static XrdPoll * newPoller(int pollid, int numfd)
Definition: XrdPollE.icc:45
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)

References XrdSysError::Emsg(), XrdGlobal::Log, XrdPollArg::Poller, XrdPollArg::retcode, XrdSysThread::Run(), TRACE, XRD_NUMPOLLERS, XrdStartPolling(), and XRDSYSTHREAD_BIND.

+ Here is the call graph for this function:

◆ Start()

virtual void XrdPoll::Start ( XrdSysSemaphore syncp,
int &  rc 
)
pure virtual

Implemented in XrdPollPoll, and XrdPollE.

Referenced by XrdStartPolling().

+ Here is the caller graph for this function:

◆ Stats()

int XrdPoll::Stats ( char *  buff,
int  blen,
int  do_sync = 0 
)
static

Definition at line 332 of file XrdPoll.cc.

333 {
334  static const char statfmt[] = "<stats id=\"poll\"><att>%d</att>"
335  "<en>%d</en><ev>%d</ev><int>%d</int></stats>";
336  int i, numatt = 0, numen = 0, numev = 0, numint = 0;
337  XrdPoll *pp;
338 
339 // Return number of bytes if so wanted
340 //
341  if (!buff) return (sizeof(statfmt)+(4*16))*XRD_NUMPOLLERS;
342 
343 // Get statistics. While we wish we could honor do_sync, doing so would be
344 // costly and hardly worth it. So, we do not include code such as:
345 // x = pp->y; if (do_sync) while(x != pp->y) x = pp->y; tot += x;
346 //
347  for (i = 0; i < XRD_NUMPOLLERS; i++)
348  {pp = Pollers[i];
349  numatt += pp->numAttached;
350  numen += pp->numEnabled;
351  numev += pp->numEvents;
352  numint += pp->numInterrupts;
353  }
354 
355 // Format and return
356 //
357  return snprintf(buff, blen, statfmt, numatt, numen, numev, numint);
358 }

References numEnabled, numEvents, numInterrupts, and XRD_NUMPOLLERS.

Member Data Documentation

◆ CmdFD

int XrdPoll::CmdFD
protected

Definition at line 117 of file XrdPoll.hh.

Referenced by XrdPollPoll::Disable(), XrdPollPoll::Enable(), and XrdPollPoll::Exclude().

◆ numEnabled

int XrdPoll::numEnabled
protected

Definition at line 132 of file XrdPoll.hh.

Referenced by XrdPollE::Enable(), and Stats().

◆ numEvents

int XrdPoll::numEvents
protected

Definition at line 133 of file XrdPoll.hh.

Referenced by XrdPollE::Start(), XrdPollPoll::Start(), and Stats().

◆ numInterrupts

int XrdPoll::numInterrupts
protected

Definition at line 134 of file XrdPoll.hh.

Referenced by XrdPollPoll::Start(), and Stats().

◆ PID

◆ PipeBlen

int XrdPoll::PipeBlen
protected

Definition at line 128 of file XrdPoll.hh.

◆ PipeBuff

char* XrdPoll::PipeBuff
protected

Definition at line 127 of file XrdPoll.hh.

◆ PipePoll

struct pollfd XrdPoll::PipePoll
protected

Definition at line 115 of file XrdPoll.hh.

◆ Pollers

XrdPoll * XrdPoll::Pollers = {0, 0, 0}
static

Definition at line 87 of file XrdPoll.hh.

◆ PollPipe

XrdSysMutex XrdPoll::PollPipe
protected

Definition at line 115 of file XrdPoll.hh.

Referenced by XrdPollPoll::Disable(), XrdPollPoll::Enable(), and XrdPollPoll::Exclude().

◆ ReqBuff

PipeData XrdPoll::ReqBuff
protected

Definition at line 126 of file XrdPoll.hh.

◆ ReqFD

int XrdPoll::ReqFD
protected

Definition at line 118 of file XrdPoll.hh.

Referenced by XrdPollPoll::Start().

◆ TID

pthread_t XrdPoll::TID

Definition at line 83 of file XrdPoll.hh.

◆ TraceID

const char * XrdPoll::TraceID = "Poll"
staticprotected

Definition at line 94 of file XrdPoll.hh.


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