XRootD
Loading...
Searching...
No Matches
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.
void DeferredFinalize ()
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.
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.
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 114 of file XrdSsiFileReq.hh.

◆ rspState

Enumerator
isNew 
isBegun 
isBound 
isAbort 
isDone 
isMax 

Definition at line 115 of file XrdSsiFileReq.hh.

Constructor & Destructor Documentation

◆ XrdSsiFileReq()

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

Definition at line 108 of file XrdSsiFileReq.hh.

109 : frqMutex(XrdSsiMutex::Recursive)
110 {Init(cID);}

Referenced by Alloc().

Here is the caller graph for this function:

◆ ~XrdSsiFileReq()

virtual XrdSsiFileReq::~XrdSsiFileReq ( )
inlinevirtual

Definition at line 112 of file XrdSsiFileReq.hh.

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

Member Function Documentation

◆ Activate()

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

Definition at line 130 of file XrdSsiFileReq.cc.

131{
132 EPNAME("Activate");
133
134// Do some debugging
135//
136 DEBUGXQ((oP ? "oucbuff" : "sfsbuff") <<" rqsz=" <<rSz);
137
138// Do statistics
139//
141 Stats.ReqCount++;
142 Stats.ReqBytes += rSz;
143 if (rSz > Stats.ReqMaxsz) Stats.ReqMaxsz = rSz;
145
146// Set request buffer pointers
147//
148 oucBuff = oP;
149 sfsBref = bR;
150 reqSize = rSz;
151
152// Now schedule ourselves to process this request. The state is new.
153//
154 Sched->Schedule((XrdJob *)this);
155}
#define EPNAME(x)
#define DEBUGXQ(x)
XrdJob(const char *desc="")
Definition XrdJob.hh:51
XrdSysMutex statsMutex
void Schedule(XrdJob *jp)
long long ReqMaxsz
long long ReqBytes
XrdSsiStats Stats
XrdScheduler * Sched

References XrdJob::XrdJob(), DEBUGXQ, EPNAME, XrdSsi::Sched, and XrdSsi::Stats.

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 161 of file XrdSsiFileReq.cc.

162{
163 EPNAME("Alert");
164 XrdSsiAlert *aP;
165 int msgLen;
166
167// Do some debugging
168//
169 aMsg.GetMsg(msgLen);
170 DEBUGXQ(msgLen <<" byte alert presented wtr=" <<respWait);
171
172// Add up statistics
173//
175
176// Lock this object
177//
178 frqMutex.Lock();
179
180// Validate the length and whether this call is allowed
181//
182 if (msgLen <= 0 || haveResp || isEnding)
183 {frqMutex.UnLock();
184 aMsg.RecycleMsg();
185 return;
186 }
187
188// Allocate an alert object and chain it into the pending queue
189//
190 aP = XrdSsiAlert::Alloc(aMsg);
191
192// Alerts must be sent in the orer they are presented. So, check if we need
193// to chain this and try to send the first in the chain. This only really
194// matters if we can send the alert now because the client is waiting.
195//
196 if (respWait)
197 {if (alrtPend)
198 {alrtLast->next = aP;
199 alrtLast = aP;
200 aP = alrtPend;
201 alrtPend = alrtPend->next;
202 }
203 WakeUp(aP);
204 } else {
205 if (alrtLast) alrtLast->next = aP;
206 else alrtPend = aP;
207 alrtLast = aP;
208 }
209
210// All done
211//
212 frqMutex.UnLock();
213}
void Bump(int &val)
static XrdSsiAlert * Alloc(XrdSsiRespInfoMsg &aMsg)
XrdSsiAlert * next
char * GetMsg(int &mlen)
virtual void RecycleMsg(bool sent=true)=0

References XrdSsiAlert::Alloc(), DEBUGXQ, EPNAME, XrdSsiRespInfoMsg::GetMsg(), XrdSsiAlert::next, XrdSsiRespInfoMsg::RecycleMsg(), 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 219 of file XrdSsiFileReq.cc.

225{
226 XrdSsiFileReq *nP;
227
228// Check if we can grab this from out queue
229//
230 aqMutex.Lock();
231 if ((nP = freeReq))
232 {freeCnt--;
233 freeReq = nP->nextReq;
234 aqMutex.UnLock();
235 nP->Init(cID);
236 } else {
237 aqMutex.UnLock();
238 nP = new XrdSsiFileReq(cID);
239 }
240
241// Initialize for processing
242//
243 if (nP)
244 {nP->sessN = sID;
245 nP->fileR = rP;
246 nP->fileP = fP;
247 nP->cbInfo = eiP;
248 nP->reqID = rnum;
249 snprintf(nP->rID, sizeof(nP->rID), "%u:", rnum);
250 }
251
252// Return the pointer
253//
254 return nP;
255}
XrdSsiFileReq(const char *cID=0)

References XrdSsiFileReq().

Here is the call graph for this function:

◆ DeferredFinalize()

void XrdSsiFileReq::DeferredFinalize ( )

Definition at line 302 of file XrdSsiFileReq.cc.

303{
304 Sched->Schedule(new FinalizeJob(this, fileP, reqID));
305}

References XrdSsi::Sched.

◆ DoIt()

void XrdSsiFileReq::DoIt ( )
virtual

Implements XrdJob.

Definition at line 332 of file XrdSsiFileReq.cc.

333{
334 EPNAME("DoIt");
335 bool cancel;
336
337// Processing is determined by the responder's state. Only listed states are
338// valid. Others should never occur in this context.
339//
340 frqMutex.Lock();
341 switch(urState)
342 {case isNew: myState = xqReq; urState = isBegun;
343 DEBUGXQ("Calling service processor");
344 frqMutex.UnLock();
347 (XrdSsiFileResource &)*fileR);
348 return;
349 break;
350 case isAbort: DEBUGXQ("Skipped calling service processor");
351 frqMutex.UnLock();
353 Recycle();
354 return;
355 break;
356 case isDone: cancel = (myState != odRsp);
357 DEBUGXQ("Calling Finished(" <<cancel <<')');
358 if (respWait) WakeUp();
359 if (finWait) finWait->Post();
360 frqMutex.UnLock();
362 if (cancel) Stats.Bump(Stats.ReqCancels);
363 Finished(cancel); // This object may be deleted!
364 return;
365 break;
366 default: break;
367 }
368
369// If we get here then we have an invalid state. Report it but otherwise we
370// can't really do anything else. This means some memory may be lost.
371//
372 frqMutex.UnLock();
373 Log.Emsg(epname, tident, "Invalid req/rsp state; giving up on object!");
374}
void Finished(XrdSsiRequest &rqstR, const XrdSsiRespInfo &rInfo, bool cancel=false)
XrdSsiRequest(const char *reqid=0, uint16_t tmo=0)
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)
XrdSsiService * Service
XrdSysError Log

References XrdSsiRequest::XrdSsiRequest(), DEBUGXQ, EPNAME, Finished(), isAbort, isBegun, isDone, isNew, XrdSsi::Log, odRsp, XrdSsi::Service, XrdSsi::Stats, and xqReq.

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 382 of file XrdSsiFileReq.cc.

383{
384 EPNAME("Done");
385 XrdSsiMutexMon mHelper(frqMutex);
386
387// We may need to delete the errinfo object if this callback was async. Note
388// that the following test is valid even if the file object has been deleted.
389//
390 if (eiP != fileP->errInfo()) delete eiP;
391
392// Check if we should finalize this request. This will be the case if the
393// complete response was sent.
394//
395 if (myState == odRsp)
396 {DEBUGXQ("resp sent; no additional data remains");
397 if (!fileP->DeferFinalize(this,reqID)) Finalize();
398 return;
399 }
400
401// Do some debugging
402//
403 DEBUGXQ("wtrsp sent; resp " <<(haveResp ? "here" : "pend"));
404
405// We are invoked when sync() waitresp has been sent, check if a response was
406// posted while this was going on. If so, make sure to send a wakeup. Note
407// that the respWait flag is at this moment false as this is called in the
408// sync response path for fctl() and the response may have been posted.
409//
410 if (!haveResp) respWait = true;
411 else WakeUp();
412}

References DEBUGXQ, EPNAME, Finalize(), and odRsp.

Here is the call graph for this function:

◆ Finalize()

void XrdSsiFileReq::Finalize ( )

Definition at line 484 of file XrdSsiFileReq.cc.

485{
486 EPNAME("Finalize");
487 XrdSsiMutexMon mHelper(frqMutex);
488 bool cancel = (myState != odRsp);
489
490// Release any unsent alerts (prevent any new alerts from being accepted)
491//
492 isEnding = true;
493 if (alrtSent || alrtPend)
494 {XrdSsiAlert *dP, *aP = alrtSent;
495 if (aP) aP->next = alrtPend;
496 else aP = alrtPend;
497 mHelper.UnLock();
498 while((dP = aP)) {aP = aP->next; dP->Recycle();}
499 mHelper.Lock(frqMutex);
500 }
501
502// Processing is determined by the responder's state
503//
504 switch(urState)
505 // Request is being scheduled, so we can simply abort it.
506 //
507 {case isNew: urState = isAbort;
508 cbInfo = 0;
509 sessN = "???";
511 DEBUGXQ("Aborting request processing");
512 return;
513 break;
514
515 // Request already handed off but not yet bound. Defer until bound.
516 // We need to wait until this occurs to sequence Unprovision().
517 //
518 case isBegun: urState = isDone;
519 {XrdSysSemaphore wt4fin(0);
520 finWait = &wt4fin;
521 mHelper.UnLock();
522 wt4fin.Wait();
523 }
524 sessN = "n/a";
525 return;
526
527 // Request is bound so we can finish right off.
528 //
529 case isBound: urState = isDone;
530 if (strBuff) {strBuff->Recycle(); strBuff = 0;}
531 DEBUGXQ("Calling Finished(" <<cancel <<')');
532 if (respWait) WakeUp();
533 mHelper.UnLock();
535 if (cancel) Stats.Bump(Stats.ReqCancels);
536 Finished(cancel); // This object may be deleted!
537 sessN = "n/a";
538 return;
539 break;
540
541 // The following two cases may happen but it's safe to ignore them.
542 //
543 case isAbort:
544 case isDone: sessN = "bad";
545 return;
546 break;
547 default: break;
548 }
549
550// If we get here then we have an invalid state. Report it but otherwise we
551// can't really do anything else. This means some memory may be lost.
552//
553 Log.Emsg(epname, tident, "Invalid req/rsp state; giving up on object!");
554}
void Recycle()

References DEBUGXQ, EPNAME, Finished(), isAbort, isBegun, isBound, isDone, isNew, XrdSsiMutexMon::Lock(), XrdSsi::Log, XrdSsiAlert::next, odRsp, XrdSsiAlert::Recycle(), XrdSsi::Stats, XrdSsiMutexMon::UnLock(), and XrdSysSemaphore::Wait().

Referenced by Done().

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

◆ Finished() [1/2]

bool XrdSsiRequest::Finished ( bool cancel = false)

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}
friend class XrdSsiResponder
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 74 of file XrdSsiFileReq.hh.

76 {}

References XrdSsiRequest::XrdSsiRequest().

Referenced by DoIt(), and Finalize().

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

◆ 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 560 of file XrdSsiFileReq.cc.

561{
562 EPNAME("GetRequest");
563
564// Do some debugging
565//
566 DEBUGXQ("sz=" <<reqSize);
568
569// The request may come from a ouc buffer or an sfs buffer
570//
571 rLen = reqSize;
572 if (oucBuff) return oucBuff->Data();
573 return XrdSfsXio::Buffer(sfsBref);
574}
static char * Buffer(XrdSfsXioHandle theHand, int *buffsz=0)
Definition XrdSfsXio.cc:61

References XrdSfsXio::Buffer(), DEBUGXQ, EPNAME, 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 617 of file XrdSsiFileReq.cc.

619{
620 EPNAME("ProcessResponse");
621
622// Do some debugging
623//
624 DEBUGXQ("Response presented wtr=" <<respWait);
625
626// Make sure we are still in execute state
627//
628 if (urState != isBegun && urState != isBound) return false;
629 myState = doRsp;
630 respOff = 0;
631
632// Handle the response
633//
634 switch(Resp.rType)
636 DEBUGXQ("Resp data sz="<<Resp.blen);
637 respLen = Resp.blen;
639 break;
641 DEBUGXQ("Resp err rc="<<Resp.eNum<<" msg="<<Resp.eMsg);
642 respLen = 0;
644 break;
646 DEBUGXQ("Resp file fd="<<Resp.fdnum<<" sz="<<Resp.fsize);
647 fileSz = Resp.fsize;
648 respOff = 0;
650 break;
652 DEBUGXQ("Resp strm");
653 respLen = 0;
655 break;
656 default:
657 DEBUGXQ("Resp invalid!!!!");
658 return false;
660 break;
661 }
662
663// If the client is waiting for the response, wake up the client to get it.
664//
665 haveResp = true;
666 if (respWait) WakeUp();
667 return true;
668}

References DEBUGXQ, doRsp, EPNAME, isBegun, isBound, XrdSsiRespInfo::isData, XrdSsiRespInfo::isError, XrdSsiRespInfo::isFile, XrdSsiRespInfo::isStream, and XrdSsi::Stats.

◆ Read()

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

Definition at line 674 of file XrdSsiFileReq.cc.

687{
688 static const char *epname = "read";
689 XrdSfsXferSize nbytes;
690 XrdSsiRespInfo const *Resp = XrdSsiRRAgent::RespP(this);
691
692// A read should never be issued unless a response has been set
693//
694 if (myState != doRsp)
695 {done = true;
696 return (myState == odRsp ? 0 : Emsg(epname, ENOMSG, "read"));
697 }
698
699// Fan out based on the kind of response we have
700//
701 switch(Resp->rType)
703 if (respLen <= 0) {done = true; myState = odRsp; return 0;}
704 if (blen >= respLen)
705 {memcpy(buff, Resp->buff+respOff, respLen);
706 blen = respLen; myState = odRsp; done = true;
707 } else {
708 memcpy(buff, Resp->buff+respOff, blen);
709 respLen -= blen; respOff += blen;
710 }
711 return blen;
712 break;
714 cbInfo->setErrInfo(Resp->eNum, Resp->eMsg);
715 myState = odRsp; done = true;
716 return SFS_ERROR;
717 break;
719 if (fileSz <= 0) {done = true; myState = odRsp; return 0;}
720 nbytes = pread(Resp->fdnum, buff, blen, respOff);
721 if (nbytes <= 0)
722 {done = true;
723 if (!nbytes) {myState = odRsp; return 0;}
724 myState = erRsp;
725 return Emsg(epname, errno, "read");
726 }
727 respOff += nbytes; fileSz -= nbytes;
728 return nbytes;
729 break;
731 nbytes = (Resp->strmP->Type() == XrdSsiStream::isActive ?
732 readStrmA(Resp->strmP, buff, blen)
733 : readStrmP(Resp->strmP, buff, blen));
734 done = strmEOF && strBuff == 0;
735 return nbytes;
736 break;
737 default: break;
738 };
739
740// We should never get here
741//
742 myState = erRsp;
743 done = true;
744 return Emsg(epname, EFAULT, "read");
745}
#define pread(a, b, c, d)
Definition XrdPosix.hh:80
#define SFS_ERROR
int XrdSfsXferSize
static XrdSsiRespInfo * RespP(XrdSsiRequest *rP)

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

Here is the call 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 853 of file XrdSsiFileReq.cc.

854{
855 EPNAME("RelReqBuff");
856 XrdSsiMutexMon mHelper(frqMutex);
857
858// Do some debugging
859//
860 DEBUGXQ("called");
862
863// Release buffers
864//
865 if (oucBuff) {oucBuff->Recycle(); oucBuff = 0;}
866 else if (sfsBref) {XrdSfsXio::Reclaim(sfsBref); sfsBref = 0;}
867 reqSize = 0;
868}
static void Reclaim(XrdSfsXioHandle theHand)
Definition XrdSfsXio.cc:70

References DEBUGXQ, EPNAME, XrdSfsXio::Reclaim(), 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 100 of file XrdSsiFileReq.hh.

101 {return 0;}

◆ Send()

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

Definition at line 874 of file XrdSsiFileReq.cc.

875{
876 static const char *epname = "send";
877 XrdSsiRespInfo const *Resp = XrdSsiRRAgent::RespP(this);
878 XrdOucSFVec sfVec[2];
879 int rc;
880
881// A send should never be issued unless a response has been set. Return a
882// continuation which will cause Read() to be called to return the error.
883//
884 if (myState != doRsp) return 1;
885
886// Fan out based on the kind of response we have
887//
888 switch(Resp->rType)
890 if (blen > 0)
891 {sfVec[1].buffer = (char *)Resp->buff+respOff;
892 sfVec[1].fdnum = -1;
893 if (blen > respLen)
894 {blen = respLen; myState = odRsp;
895 } else {
896 respLen -= blen; respOff += blen;
897 }
898 } else blen = 0;
899 break;
901 return 1; // Causes error to be returned via Read()
902 break;
904 if (fileSz > 0)
905 {sfVec[1].offset = respOff; sfVec[1].fdnum = Resp->fdnum;
906 if (blen > fileSz)
907 {blen = fileSz; myState = odRsp;}
908 respOff += blen; fileSz -= blen;
909 } else blen = 0;
910 break;
912 if (Resp->strmP->Type() == XrdSsiStream::isPassive) return 1;
913 return sendStrmA(Resp->strmP, sfDio, blen);
914 break;
915 default: myState = erRsp;
916 return Emsg(epname, EFAULT, "send");
917 break;
918 };
919
920// Send off the data
921//
922 if (!blen) {sfVec[1].buffer = rID; myState = odRsp;}
923 sfVec[1].sendsz = blen;
924 rc = sfDio->SendFile(sfVec, 2);
925
926// If send succeeded, indicate the action to be taken
927//
928 if (!rc) return myState != odRsp;
929
930// The send failed, diagnose the problem
931//
932 rc = (rc < 0 ? EIO : EFAULT);
933 myState = erRsp;
934 return Emsg(epname, rc, "send");
935}
virtual int SendFile(int fildes)=0
int fdnum
File descriptor for data.
int sendsz
Length of data at offset.

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

Here is the call graph for this function:

◆ SetMax()

void XrdSsiFileReq::SetMax ( int mVal)
inlinestatic

Definition at line 91 of file XrdSsiFileReq.hh.

91{freeMax = mVal;}

◆ WantResponse()

bool XrdSsiFileReq::WantResponse ( XrdOucErrInfo & eInfo)

Definition at line 996 of file XrdSsiFileReq.cc.

997{
998 EPNAME("WantResp");
999 XrdSsiMutexMon frqMon;
1000 const XrdSsiRespInfo *rspP;
1001
1002// Check if we have a previos alert that was sent (we need to recycle it). We
1003// don't need a lock for this as it's fully serialized via serial fsctl calls.
1004//
1005 if (alrtSent) {alrtSent->Recycle(); alrtSent = 0;}
1006
1007// Serialize the remainder of this code
1008//
1009 frqMon.Lock(frqMutex);
1010 rspP = XrdSsiRRAgent::RespP(this);
1011
1012// If we have a pending alert then we need to send it now. Suppress the callback
1013// as we will recycle the alert on the next call (there should be one).
1014//
1015 if (alrtPend)
1016 {char hexBuff[16], binBuff[8], dotBuff[4];
1017 alrtSent = alrtPend;
1018 if (!(alrtPend = alrtPend->next)) alrtLast = 0;
1019 int n = alrtSent->SetInfo(eInfo, binBuff, sizeof(binBuff));
1020 eInfo.setErrCB((XrdOucEICB *)0);
1021 DEBUGXQ(n <<" byte alert (0x" <<DUMPIT(binBuff, n) <<") sent; "
1022 <<(alrtPend ? "" : "no ") <<"more pending");
1023 return true;
1024 }
1025
1026// Check if a response is here (well, ProcessResponse was called)
1027//
1028// if (rspP->rType)
1029 if (haveResp)
1030 {respCBarg = 0;
1031 if (fileP->AttnInfo(eInfo, rspP, reqID)) myState = odRsp;
1032 else eInfo.setErrCB((XrdOucEICB *)0);
1033 return true;
1034 }
1035
1036// Defer this and record the callback arguments. We defer setting respWait
1037// to true until we know the deferal request has been sent (i.e. when Done()
1038// is called). This forces ProcessResponse() to not prematurely wakeup the
1039// client. This is necessitated by the fact that we must release the request
1040// lock upon return; allowing a response to come in while the deferal request
1041// is still in transit.
1042//
1043 respCB = eInfo.getErrCB(respCBarg);
1044 respWait = false;
1045 return false;
1046}
#define DUMPIT(x, y)
XrdOucEICB()
Constructor and destructor.
XrdOucEICB * getErrCB()
void setErrCB(XrdOucEICB *cb, unsigned long long cbarg=0)
void Lock(XrdSsiMutex *mutex)

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

Here is the call graph for this function:

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