XRootD
XrdSsiFileReq Class Reference

#include <XrdSsiFileReq.hh>

+ Inheritance diagram for XrdSsiFileReq:
+ Collaboration diagram for XrdSsiFileReq:

Public Types

enum  reqState {
  wtReq =0 ,
  xqReq ,
  wtRsp ,
  doRsp ,
  odRsp ,
  erRsp ,
  rsEnd
}
 
enum  rspState {
  isNew =0 ,
  isBegun ,
  isBound ,
  isAbort ,
  isDone ,
  isMax
}
 

Public Member Functions

 XrdSsiFileReq (const char *cID=0)
 
virtual ~XrdSsiFileReq ()
 
void Activate (XrdOucBuffer *oP, XrdSfsXioHandle bR, int rSz)
 
void Alert (XrdSsiRespInfoMsg &aMsg)
 Send or receive a server generated alert. More...
 
void DoIt ()
 
void Done (int &Result, XrdOucErrInfo *cbInfo, const char *path=0)
 
void Finalize ()
 
bool Finished (bool cancel=false)
 
void Finished (XrdSsiRequest &rqstR, const XrdSsiRespInfo &rInfo, bool cancel=false)
 
char * GetRequest (int &rLen)
 
bool ProcessResponse (const XrdSsiErrInfo &eInfo, const XrdSsiRespInfo &resp)
 
XrdSfsXferSize Read (bool &done, char *buffer, XrdSfsXferSize blen)
 
void RelRequestBuffer ()
 
int Same (unsigned long long arg1, unsigned long long arg2)
 
int Send (XrdSfsDio *sfDio, XrdSfsXferSize size)
 
bool WantResponse (XrdOucErrInfo &eInfo)
 
- Public Member Functions inherited from XrdSsiRequest
 XrdSsiRequest (const char *reqid=0, uint16_t tmo=0)
 
bool Finished (bool cancel=false)
 
uint32_t GetDetachTTL ()
 
std::string GetEndPoint ()
 
const char * GetMetadata (int &dlen)
 
const char * GetRequestID ()
 
void GetResponseData (char *buff, int blen)
 
uint16_t GetTimeOut ()
 
virtual void ProcessResponseData (const XrdSsiErrInfo &eInfo, char *buff, int blen, bool last)
 
void ReleaseRequestBuffer ()
 
- Public Member Functions inherited from XrdOucEICB
 XrdOucEICB ()
 Constructor and destructor. More...
 
virtual ~XrdOucEICB ()
 
- Public Member Functions inherited from XrdJob
 XrdJob (const char *desc="")
 
virtual ~XrdJob ()
 

Static Public Member Functions

static XrdSsiFileReqAlloc (XrdOucErrInfo *eP, XrdSsiFileResource *rP, XrdSsiFileSess *fP, const char *sn, const char *id, unsigned int rnum)
 
static void SetMax (int mVal)
 

Additional Inherited Members

- Public Attributes inherited from XrdJob
const char * Comment
 
XrdJobNextJob
 
- Protected Member Functions inherited from XrdSsiRequest
virtual ~XrdSsiRequest ()
 
void SetDetachTTL (uint32_t dttl)
 Set the detached request time to live value. More...
 
void SetRetry (bool onoff)
 
void SetTimeOut (uint16_t tmo)
 

Detailed Description

Definition at line 53 of file XrdSsiFileReq.hh.

Member Enumeration Documentation

◆ reqState

Enumerator
wtReq 
xqReq 
wtRsp 
doRsp 
odRsp 
erRsp 
rsEnd 

Definition at line 112 of file XrdSsiFileReq.hh.

◆ rspState

Enumerator
isNew 
isBegun 
isBound 
isAbort 
isDone 
isMax 

Definition at line 113 of file XrdSsiFileReq.hh.

Constructor & Destructor Documentation

◆ XrdSsiFileReq()

XrdSsiFileReq::XrdSsiFileReq ( const char *  cID = 0)
inline

Definition at line 106 of file XrdSsiFileReq.hh.

107  : frqMutex(XrdSsiMutex::Recursive)
108  {Init(cID);}

◆ ~XrdSsiFileReq()

virtual XrdSsiFileReq::~XrdSsiFileReq ( )
inlinevirtual

Definition at line 110 of file XrdSsiFileReq.hh.

110 {if (tident) free(tident);}

Member Function Documentation

◆ Activate()

void XrdSsiFileReq::Activate ( XrdOucBuffer oP,
XrdSfsXioHandle  bR,
int  rSz 
)

Definition at line 104 of file XrdSsiFileReq.cc.

105 {
106  EPNAME("Activate");
107 
108 // Do some debugging
109 //
110  DEBUGXQ((oP ? "oucbuff" : "sfsbuff") <<" rqsz=" <<rSz);
111 
112 // Do statistics
113 //
114  Stats.statsMutex.Lock();
115  Stats.ReqCount++;
116  Stats.ReqBytes += rSz;
117  if (rSz > Stats.ReqMaxsz) Stats.ReqMaxsz = rSz;
118  Stats.statsMutex.UnLock();
119 
120 // Set request buffer pointers
121 //
122  oucBuff = oP;
123  sfsBref = bR;
124  reqSize = rSz;
125 
126 // Now schedule ourselves to process this request. The state is new.
127 //
128  Sched->Schedule((XrdJob *)this);
129 }
#define EPNAME(x)
Definition: XrdBwmTrace.hh:56
#define DEBUGXQ(x)
Definition: XrdJob.hh:43
void Schedule(XrdJob *jp)
XrdPosixStats Stats
Definition: XrdPosixFile.cc:64
XrdScheduler * Sched

References DEBUGXQ, EPNAME, XrdSysMutex::Lock(), XrdSsiStats::ReqBytes, XrdSsiStats::ReqCount, XrdSsiStats::ReqMaxsz, XrdSsi::Sched, XrdScheduler::Schedule(), XrdSsi::Stats, XrdOucStats::statsMutex, and XrdSysMutex::UnLock().

+ Here is the call graph for this function:

◆ Alert()

void XrdSsiFileReq::Alert ( XrdSsiRespInfoMsg aMsg)
virtual

Send or receive a server generated alert.

The Alert() method is used server-side to send one or more alerts before a response is posted (alerts afterwards are ignored). To avoid race conditions, server-side alerts should be sent via the Responder's Alert() method. Clients must implement this method in order to receive alerts.

Parameters
aMsgReference to the message object containing the alert message. Non-positive alert lengths cause the alert call to be ignored. You should call the message RecycleMsg() method once you have consumed the message to release its resources.

Reimplemented from XrdSsiRequest.

Definition at line 135 of file XrdSsiFileReq.cc.

136 {
137  EPNAME("Alert");
138  XrdSsiAlert *aP;
139  int msgLen;
140 
141 // Do some debugging
142 //
143  aMsg.GetMsg(msgLen);
144  DEBUGXQ(msgLen <<" byte alert presented wtr=" <<respWait);
145 
146 // Add up statistics
147 //
148  Stats.Bump(Stats.ReqAlerts);
149 
150 // Lock this object
151 //
152  frqMutex.Lock();
153 
154 // Validate the length and whether this call is allowed
155 //
156  if (msgLen <= 0 || haveResp || isEnding)
157  {frqMutex.UnLock();
158  aMsg.RecycleMsg();
159  return;
160  }
161 
162 // Allocate an alert object and chain it into the pending queue
163 //
164  aP = XrdSsiAlert::Alloc(aMsg);
165 
166 // Alerts must be sent in the orer they are presented. So, check if we need
167 // to chain this and try to send the first in the chain. This only really
168 // matters if we can send the alert now because the client is waiting.
169 //
170  if (respWait)
171  {if (alrtPend)
172  {alrtLast->next = aP;
173  alrtLast = aP;
174  aP = alrtPend;
175  alrtPend = alrtPend->next;
176  }
177  WakeUp(aP);
178  } else {
179  if (alrtLast) alrtLast->next = aP;
180  else alrtPend = aP;
181  alrtLast = aP;
182  }
183 
184 // All done
185 //
186  frqMutex.UnLock();
187 }
static XrdSsiAlert * Alloc(XrdSsiRespInfoMsg &aMsg)
Definition: XrdSsiAlert.cc:52
XrdSsiAlert * next
Definition: XrdSsiAlert.hh:41
char * GetMsg(int &mlen)
virtual void RecycleMsg(bool sent=true)=0

References XrdSsiAlert::Alloc(), XrdOucStats::Bump(), DEBUGXQ, EPNAME, XrdSsiRespInfoMsg::GetMsg(), XrdSsiAlert::next, XrdSsiRespInfoMsg::RecycleMsg(), XrdSsiStats::ReqAlerts, and XrdSsi::Stats.

+ Here is the call graph for this function:

◆ Alloc()

XrdSsiFileReq * XrdSsiFileReq::Alloc ( XrdOucErrInfo eP,
XrdSsiFileResource rP,
XrdSsiFileSess fP,
const char *  sn,
const char *  id,
unsigned int  rnum 
)
static

Definition at line 193 of file XrdSsiFileReq.cc.

199 {
200  XrdSsiFileReq *nP;
201 
202 // Check if we can grab this from out queue
203 //
204  aqMutex.Lock();
205  if ((nP = freeReq))
206  {freeCnt--;
207  freeReq = nP->nextReq;
208  aqMutex.UnLock();
209  nP->Init(cID);
210  } else {
211  aqMutex.UnLock();
212  nP = new XrdSsiFileReq(cID);
213  }
214 
215 // Initialize for processing
216 //
217  if (nP)
218  {nP->sessN = sID;
219  nP->fileR = rP;
220  nP->fileP = fP;
221  nP->cbInfo = eiP;
222  nP->reqID = rnum;
223  snprintf(nP->rID, sizeof(nP->rID), "%u:", rnum);
224  }
225 
226 // Return the pointer
227 //
228  return nP;
229 }
XrdSsiFileReq(const char *cID=0)

◆ DoIt()

void XrdSsiFileReq::DoIt ( )
virtual

Implements XrdJob.

Definition at line 297 of file XrdSsiFileReq.cc.

298 {
299  EPNAME("DoIt");
300  bool cancel;
301 
302 // Processing is determined by the responder's state. Only listed states are
303 // valid. Others should never occur in this context.
304 //
305  frqMutex.Lock();
306  switch(urState)
307  {case isNew: myState = xqReq; urState = isBegun;
308  DEBUGXQ("Calling service processor");
309  frqMutex.UnLock();
310  Stats.Bump(Stats.ReqProcs);
312  (XrdSsiFileResource &)*fileR);
313  return;
314  break;
315  case isAbort: DEBUGXQ("Skipped calling service processor");
316  frqMutex.UnLock();
317  Stats.Bump(Stats.ReqAborts);
318  Recycle();
319  return;
320  break;
321  case isDone: cancel = (myState != odRsp);
322  DEBUGXQ("Calling Finished(" <<cancel <<')');
323  if (respWait) WakeUp();
324  if (finWait) finWait->Post();
325  frqMutex.UnLock();
326  Stats.Bump(Stats.ReqFinished);
327  if (cancel) Stats.Bump(Stats.ReqCancels);
328  Finished(cancel); // This object may be deleted!
329  return;
330  break;
331  default: break;
332  }
333 
334 // If we get here then we have an invalid state. Report it but otherwise we
335 // can't really do anything else. This means some memory may be lost.
336 //
337  frqMutex.UnLock();
338  Log.Emsg(epname, tident, "Invalid req/rsp state; giving up on object!");
339 }
bool Finished(bool cancel=false)
virtual void ProcessRequest(XrdSsiRequest &reqRef, XrdSsiResource &resRef)=0
Process a request; client-side or server-side.
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
XrdSysError Log
Definition: XrdConfig.cc:112
XrdSsiService * Service

References XrdOucStats::Bump(), DEBUGXQ, XrdSysError::Emsg(), EPNAME, XrdSsi::Log, XrdSsiService::ProcessRequest(), XrdSsiStats::ReqAborts, XrdSsiStats::ReqCancels, XrdSsiStats::ReqFinished, XrdSsiStats::ReqProcs, XrdSsi::Service, XrdSsi::Stats, and tident.

+ Here is the call graph for this function:

◆ Done()

void XrdSsiFileReq::Done ( int &  Result,
XrdOucErrInfo eInfo,
const char *  Path = 0 
)
virtual

Invoke a callback after an operation completes.

Parameters
Result- the original function's result (may be changed).
eInfo- Associated error information. The eInfo object may not be modified until it's own callback Done() method is called, if supplied. If the callback function in eInfo is zero, then the eInfo object is deleted by the invoked callback. Otherwise, that method must be invoked by this callback function after the actual callback message is sent. This allows the callback requestor to do post-processing and be asynchronous being assured that the callback completed.
Path- Optionally, the path related to thid request. It is used for tracing and detailed monitoring purposes.

Implements XrdOucEICB.

Definition at line 347 of file XrdSsiFileReq.cc.

348 {
349  EPNAME("Done");
350  XrdSsiMutexMon mHelper(frqMutex);
351 
352 // We may need to delete the errinfo object if this callback was async. Note
353 // that the following test is valid even if the file object has been deleted.
354 //
355  if (eiP != fileP->errInfo()) delete eiP;
356 
357 // Check if we should finalize this request. This will be the case if the
358 // complete response was sent.
359 //
360  if (myState == odRsp)
361  {DEBUGXQ("resp sent; no additional data remains");
362  Finalize();
363  return;
364  }
365 
366 // Do some debugging
367 //
368  DEBUGXQ("wtrsp sent; resp " <<(haveResp ? "here" : "pend"));
369 
370 // We are invoked when sync() waitresp has been sent, check if a response was
371 // posted while this was going on. If so, make sure to send a wakeup. Note
372 // that the respWait flag is at this moment false as this is called in the
373 // sync response path for fctl() and the response may have been posted.
374 //
375  if (!haveResp) respWait = true;
376  else WakeUp();
377 }
XrdOucErrInfo * errInfo()

References DEBUGXQ, and EPNAME.

◆ Finalize()

void XrdSsiFileReq::Finalize ( )

Definition at line 449 of file XrdSsiFileReq.cc.

450 {
451  EPNAME("Finalize");
452  XrdSsiMutexMon mHelper(frqMutex);
453  bool cancel = (myState != odRsp);
454 
455 // Release any unsent alerts (prevent any new alerts from being accepted)
456 //
457  isEnding = true;
458  if (alrtSent || alrtPend)
459  {XrdSsiAlert *dP, *aP = alrtSent;
460  if (aP) aP->next = alrtPend;
461  else aP = alrtPend;
462  mHelper.UnLock();
463  while((dP = aP)) {aP = aP->next; dP->Recycle();}
464  mHelper.Lock(frqMutex);
465  }
466 
467 // Processing is determined by the responder's state
468 //
469  switch(urState)
470  // Request is being scheduled, so we can simply abort it.
471  //
472  {case isNew: DEBUGXQ("Aborting request processing");
473  urState = isAbort;
474  cbInfo = 0;
475  sessN = "???";
476  Stats.Bump(Stats.ReqAborts);
477  return;
478  break;
479 
480  // Request already handed off but not yet bound. Defer until bound.
481  // We need to wait until this occurs to sequence Unprovision().
482  //
483  case isBegun: urState = isDone;
484  {XrdSysSemaphore wt4fin(0);
485  finWait = &wt4fin;
486  mHelper.UnLock();
487  wt4fin.Wait();
488  }
489  sessN = "n/a";
490  return;
491 
492  // Request is bound so we can finish right off.
493  //
494  case isBound: urState = isDone;
495  if (strBuff) {strBuff->Recycle(); strBuff = 0;}
496  DEBUGXQ("Calling Finished(" <<cancel <<')');
497  if (respWait) WakeUp();
498  mHelper.UnLock();
499  Stats.Bump(Stats.ReqFinished);
500  if (cancel) Stats.Bump(Stats.ReqCancels);
501  Finished(cancel); // This object may be deleted!
502  sessN = "n/a";
503  return;
504  break;
505 
506  // The following two cases may happen but it's safe to ignore them.
507  //
508  case isAbort:
509  case isDone: sessN = "bad";
510  return;
511  break;
512  default: break;
513  }
514 
515 // If we get here then we have an invalid state. Report it but otherwise we
516 // can't really do anything else. This means some memory may be lost.
517 //
518  Log.Emsg(epname, tident, "Invalid req/rsp state; giving up on object!");
519 }
void Recycle()
Definition: XrdSsiAlert.cc:98
virtual void Recycle()=0

References XrdOucStats::Bump(), DEBUGXQ, XrdSysError::Emsg(), EPNAME, XrdSsiMutexMon::Lock(), XrdSsi::Log, XrdSsiAlert::next, XrdSsiAlert::Recycle(), XrdSsiStats::ReqAborts, XrdSsiStats::ReqCancels, XrdSsiStats::ReqFinished, XrdSsi::Stats, tident, XrdSsiMutexMon::UnLock(), and XrdSysSemaphore::Wait().

Referenced by XrdSsiFileSess::read(), XrdSsiFileSess::SendData(), and XrdSsiFileSess::truncate().

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

◆ Finished() [1/2]

bool XrdSsiRequest::Finished

Indicate that request processing has been finished. This method calls XrdSsiResponder::Finished() on the associated responder object.

Note: This method locks the object's recursive mutex.

Parameters
cancelFalse -> the request/response sequence completed normally. True -> the request/response sequence aborted because of an error or the client cancelled the request.
Returns
true Finish accepted. Request object may be reclaimed.
false Finish cannot be accepted because this request object is not bound to a responder. This indicates a logic error.

Definition at line 91 of file XrdSsiRequest.cc.

116 {
117  XrdSsiResponder *respP;
118 
119 // Obtain the responder
120 //
121  rrMutex->Lock();
122  respP = theRespond;
123  theRespond = 0;
124  rrMutex->UnLock();
125 
126 // Tell any responder we are finished (we might not have one)
127 //
128  if (respP) respP->Finished(*this, Resp, cancel);
129 
130 // We are done. The object will be reiniialized when UnBindRequest() is
131 // called which will call UnBind() in this object. Since the timing is not
132 // known we can't touch anthing in this object at this point.
133 // Return false if there was no responder associated with this request.
134 //
135  return respP != 0;
136 }
virtual void Finished(XrdSsiRequest &rqstR, const XrdSsiRespInfo &rInfo, bool cancel=false)=0

◆ Finished() [2/2]

void XrdSsiFileReq::Finished ( XrdSsiRequest rqstR,
const XrdSsiRespInfo rInfo,
bool  cancel = false 
)
inline

Definition at line 72 of file XrdSsiFileReq.hh.

74  {}

◆ GetRequest()

char * XrdSsiFileReq::GetRequest ( int &  dlen)
virtual

Obtain the request data sent by a client.

This method is duplicated in XrdSsiResponder to allow calling consistency.

Parameters
dlenholds the length of the request after the call.
Returns
=0 No request data available, dlen has been set to zero.
!0 Pointer to the buffer holding the request, dlen has the length

Implements XrdSsiRequest.

Definition at line 525 of file XrdSsiFileReq.cc.

526 {
527  EPNAME("GetRequest");
528 
529 // Do some debugging
530 //
531  DEBUGXQ("sz=" <<reqSize);
532  Stats.Bump(Stats.ReqGets);
533 
534 // The request may come from a ouc buffer or an sfs buffer
535 //
536  rLen = reqSize;
537  if (oucBuff) return oucBuff->Data();
538  return XrdSfsXio::Buffer(sfsBref);
539 }
char * Data() const
static char * Buffer(XrdSfsXioHandle theHand, int *buffsz=0)
Definition: XrdSfsXio.cc:61

References XrdSfsXio::Buffer(), XrdOucStats::Bump(), DEBUGXQ, EPNAME, XrdSsiStats::ReqGets, and XrdSsi::Stats.

+ Here is the call graph for this function:

◆ ProcessResponse()

bool XrdSsiFileReq::ProcessResponse ( const XrdSsiErrInfo eInfo,
const XrdSsiRespInfo rInfo 
)
virtual

Notify request that a response is ready to be processed. This method must be supplied by the request object's implementation.

Parameters
eInfoError information. You can check if an error occurred using eInfo.hasError() or eInfo.isOK().
rInfoRaw response information.
Returns
true Response processed.
false Response could not be processed, the request is not active.

Implements XrdSsiRequest.

Definition at line 582 of file XrdSsiFileReq.cc.

584 {
585  EPNAME("ProcessResponse");
586 
587 // Do some debugging
588 //
589  DEBUGXQ("Response presented wtr=" <<respWait);
590 
591 // Make sure we are still in execute state
592 //
593  if (urState != isBegun && urState != isBound) return false;
594  myState = doRsp;
595  respOff = 0;
596 
597 // Handle the response
598 //
599  switch(Resp.rType)
601  DEBUGXQ("Resp data sz="<<Resp.blen);
602  respLen = Resp.blen;
603  Stats.Bump(Stats.RspData);
604  break;
606  DEBUGXQ("Resp err rc="<<Resp.eNum<<" msg="<<Resp.eMsg);
607  respLen = 0;
608  Stats.Bump(Stats.RspErrs);
609  break;
611  DEBUGXQ("Resp file fd="<<Resp.fdnum<<" sz="<<Resp.fsize);
612  fileSz = Resp.fsize;
613  respOff = 0;
614  Stats.Bump(Stats.RspFile);
615  break;
617  DEBUGXQ("Resp strm");
618  respLen = 0;
619  Stats.Bump(Stats.RspStrm);
620  break;
621  default:
622  DEBUGXQ("Resp invalid!!!!");
623  return false;
624  Stats.Bump(Stats.RspBad);
625  break;
626  }
627 
628 // If the client is waiting for the response, wake up the client to get it.
629 //
630  haveResp = true;
631  if (respWait) WakeUp();
632  return true;
633 }

References XrdOucStats::Bump(), DEBUGXQ, EPNAME, XrdSsiRespInfo::isData, XrdSsiRespInfo::isError, XrdSsiRespInfo::isFile, XrdSsiRespInfo::isStream, XrdSsiStats::RspBad, XrdSsiStats::RspData, XrdSsiStats::RspErrs, XrdSsiStats::RspFile, XrdSsiStats::RspStrm, XrdSsiRespInfo::rType, and XrdSsi::Stats.

+ Here is the call graph for this function:

◆ Read()

XrdSfsXferSize XrdSsiFileReq::Read ( bool &  done,
char *  buffer,
XrdSfsXferSize  blen 
)

Definition at line 639 of file XrdSsiFileReq.cc.

652 {
653  static const char *epname = "read";
654  XrdSfsXferSize nbytes;
655  XrdSsiRespInfo const *Resp = XrdSsiRRAgent::RespP(this);
656 
657 // A read should never be issued unless a response has been set
658 //
659  if (myState != doRsp)
660  {done = true;
661  return (myState == odRsp ? 0 : Emsg(epname, ENOMSG, "read"));
662  }
663 
664 // Fan out based on the kind of response we have
665 //
666  switch(Resp->rType)
668  if (respLen <= 0) {done = true; myState = odRsp; return 0;}
669  if (blen >= respLen)
670  {memcpy(buff, Resp->buff+respOff, respLen);
671  blen = respLen; myState = odRsp; done = true;
672  } else {
673  memcpy(buff, Resp->buff+respOff, blen);
674  respLen -= blen; respOff += blen;
675  }
676  return blen;
677  break;
679  cbInfo->setErrInfo(Resp->eNum, Resp->eMsg);
680  myState = odRsp; done = true;
681  return SFS_ERROR;
682  break;
684  if (fileSz <= 0) {done = true; myState = odRsp; return 0;}
685  nbytes = pread(Resp->fdnum, buff, blen, respOff);
686  if (nbytes <= 0)
687  {done = true;
688  if (!nbytes) {myState = odRsp; return 0;}
689  myState = erRsp;
690  return Emsg(epname, errno, "read");
691  }
692  respOff += nbytes; fileSz -= nbytes;
693  return nbytes;
694  break;
696  nbytes = (Resp->strmP->Type() == XrdSsiStream::isActive ?
697  readStrmA(Resp->strmP, buff, blen)
698  : readStrmP(Resp->strmP, buff, blen));
699  done = strmEOF && strBuff == 0;
700  return nbytes;
701  break;
702  default: break;
703  };
704 
705 // We should never get here
706 //
707  myState = erRsp;
708  done = true;
709  return Emsg(epname, EFAULT, "read");
710 }
ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset)
#define SFS_ERROR
int XrdSfsXferSize
int setErrInfo(int code, const char *emsg)
static XrdSsiRespInfo * RespP(XrdSsiRequest *rP)

References XrdSsiStream::isActive, XrdSsiRespInfo::isData, XrdSsiRespInfo::isError, XrdSsiRespInfo::isFile, XrdSsiRespInfo::isStream, pread(), XrdSsiRRAgent::RespP(), XrdSsiRespInfo::rType, and SFS_ERROR.

Referenced by XrdSsiFileSess::read().

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

◆ RelRequestBuffer()

void XrdSsiFileReq::RelRequestBuffer ( )
virtual

Release the request buffer. Use this method to optimize storage use; this is especially relevant for long-running requests. If the request buffer has been consumed and is no longer needed, early return of the buffer will minimize memory usage. This method is also invoked via XrdSsiResponder.

Note: This method is called with the object's recursive mutex locked when it is invoked via XrdSsiResponder's ReleaseRequestBuffer().

Reimplemented from XrdSsiRequest.

Definition at line 818 of file XrdSsiFileReq.cc.

819 {
820  EPNAME("RelReqBuff");
821  XrdSsiMutexMon mHelper(frqMutex);
822 
823 // Do some debugging
824 //
825  DEBUGXQ("called");
826  Stats.Bump(Stats.ReqRelBuf);
827 
828 // Release buffers
829 //
830  if (oucBuff) {oucBuff->Recycle(); oucBuff = 0;}
831  else if (sfsBref) {XrdSfsXio::Reclaim(sfsBref); sfsBref = 0;}
832  reqSize = 0;
833 }
void Recycle()
Recycle the buffer. The buffer may be reused in the future.
static void Reclaim(XrdSfsXioHandle theHand)
Definition: XrdSfsXio.cc:70

References XrdOucStats::Bump(), DEBUGXQ, EPNAME, XrdSfsXio::Reclaim(), XrdSsiStats::ReqRelBuf, and XrdSsi::Stats.

+ Here is the call graph for this function:

◆ Same()

int XrdSsiFileReq::Same ( unsigned long long  arg1,
unsigned long long  arg2 
)
inlinevirtual

Determine if two callback arguments refer to the same client.

Parameters
arg1- The first callback argument.
arg2- The second callback argument.
Returns
!0 - The arguments refer to the same client.
=0 - The arguments refer to the different clients.

Implements XrdOucEICB.

Definition at line 98 of file XrdSsiFileReq.hh.

99  {return 0;}

◆ Send()

int XrdSsiFileReq::Send ( XrdSfsDio sfDio,
XrdSfsXferSize  size 
)

Definition at line 839 of file XrdSsiFileReq.cc.

840 {
841  static const char *epname = "send";
842  XrdSsiRespInfo const *Resp = XrdSsiRRAgent::RespP(this);
843  XrdOucSFVec sfVec[2];
844  int rc;
845 
846 // A send should never be issued unless a response has been set. Return a
847 // continuation which will cause Read() to be called to return the error.
848 //
849  if (myState != doRsp) return 1;
850 
851 // Fan out based on the kind of response we have
852 //
853  switch(Resp->rType)
855  if (blen > 0)
856  {sfVec[1].buffer = (char *)Resp->buff+respOff;
857  sfVec[1].fdnum = -1;
858  if (blen > respLen)
859  {blen = respLen; myState = odRsp;
860  } else {
861  respLen -= blen; respOff += blen;
862  }
863  } else blen = 0;
864  break;
866  return 1; // Causes error to be returned via Read()
867  break;
869  if (fileSz > 0)
870  {sfVec[1].offset = respOff; sfVec[1].fdnum = Resp->fdnum;
871  if (blen > fileSz)
872  {blen = fileSz; myState = odRsp;}
873  respOff += blen; fileSz -= blen;
874  } else blen = 0;
875  break;
877  if (Resp->strmP->Type() == XrdSsiStream::isPassive) return 1;
878  return sendStrmA(Resp->strmP, sfDio, blen);
879  break;
880  default: myState = erRsp;
881  return Emsg(epname, EFAULT, "send");
882  break;
883  };
884 
885 // Send off the data
886 //
887  if (!blen) {sfVec[1].buffer = rID; myState = odRsp;}
888  sfVec[1].sendsz = blen;
889  rc = sfDio->SendFile(sfVec, 2);
890 
891 // If send succeeded, indicate the action to be taken
892 //
893  if (!rc) return myState != odRsp;
894 
895 // The send failed, diagnose the problem
896 //
897  rc = (rc < 0 ? EIO : EFAULT);
898  myState = erRsp;
899  return Emsg(epname, rc, "send");
900 }
if(Avsz)
virtual int SendFile(int fildes)=0
int fdnum
File descriptor for data.
Definition: XrdOucSFVec.hh:47
int sendsz
Length of data at offset.
Definition: XrdOucSFVec.hh:46

References XrdOucSFVec::fdnum, if(), XrdSsiRespInfo::isData, XrdSsiRespInfo::isError, XrdSsiRespInfo::isFile, XrdSsiStream::isPassive, XrdSsiRespInfo::isStream, XrdSsiRRAgent::RespP(), XrdSsiRespInfo::rType, XrdSfsDio::SendFile(), and XrdOucSFVec::sendsz.

Referenced by XrdSsiFileSess::SendData().

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

◆ SetMax()

static void XrdSsiFileReq::SetMax ( int  mVal)
inlinestatic

Definition at line 89 of file XrdSsiFileReq.hh.

89 {freeMax = mVal;}

◆ WantResponse()

bool XrdSsiFileReq::WantResponse ( XrdOucErrInfo eInfo)

Definition at line 961 of file XrdSsiFileReq.cc.

962 {
963  EPNAME("WantResp");
964  XrdSsiMutexMon frqMon;
965  const XrdSsiRespInfo *rspP;
966 
967 // Check if we have a previos alert that was sent (we need to recycle it). We
968 // don't need a lock for this as it's fully serialized via serial fsctl calls.
969 //
970  if (alrtSent) {alrtSent->Recycle(); alrtSent = 0;}
971 
972 // Serialize the remainder of this code
973 //
974  frqMon.Lock(frqMutex);
975  rspP = XrdSsiRRAgent::RespP(this);
976 
977 // If we have a pending alert then we need to send it now. Suppress the callback
978 // as we will recycle the alert on the next call (there should be one).
979 //
980  if (alrtPend)
981  {char hexBuff[16], binBuff[8], dotBuff[4];
982  alrtSent = alrtPend;
983  if (!(alrtPend = alrtPend->next)) alrtLast = 0;
984  int n = alrtSent->SetInfo(eInfo, binBuff, sizeof(binBuff));
985  eInfo.setErrCB((XrdOucEICB *)0);
986  DEBUGXQ(n <<" byte alert (0x" <<DUMPIT(binBuff, n) <<") sent; "
987  <<(alrtPend ? "" : "no ") <<"more pending");
988  return true;
989  }
990 
991 // Check if a response is here (well, ProcessResponse was called)
992 //
993 // if (rspP->rType)
994  if (haveResp)
995  {respCBarg = 0;
996  if (fileP->AttnInfo(eInfo, rspP, reqID))
997  { eInfo.setErrCB((XrdOucEICB *)this); myState = odRsp;}
998  else eInfo.setErrCB((XrdOucEICB *)0);
999  return true;
1000  }
1001 
1002 // Defer this and record the callback arguments. We defer setting respWait
1003 // to true until we know the deferal request has been sent (i.e. when Done()
1004 // is called). This forces ProcessResponse() to not prematurely wakeup the
1005 // client. This is necessitated by the fact that we must release the request
1006 // lock upon return; allowing a response to come in while the deferal request
1007 // is still in transit.
1008 //
1009  respCB = eInfo.getErrCB(respCBarg);
1010  respWait = false;
1011  return false;
1012 }
#define DUMPIT(x, y)
XrdOucEICB * getErrCB()
void setErrCB(XrdOucEICB *cb, unsigned long long cbarg=0)
int SetInfo(XrdOucErrInfo &eInfo, char *aMsg, int aLen)
Definition: XrdSsiAlert.cc:117
bool AttnInfo(XrdOucErrInfo &eInfo, const XrdSsiRespInfo *respP, unsigned int reqID)
void Lock(XrdSsiMutex *mutex)

References DEBUGXQ, DUMPIT, EPNAME, XrdOucErrInfo::getErrCB(), XrdSsiMutexMon::Lock(), XrdSsiRRAgent::RespP(), and XrdOucErrInfo::setErrCB().

Referenced by XrdSsiFileSess::fctl().

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

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