XRootD
Loading...
Searching...
No Matches
XrdSsiTaskReal Class Reference

#include <XrdSsiTaskReal.hh>

+ Inheritance diagram for XrdSsiTaskReal:
+ Collaboration diagram for XrdSsiTaskReal:

Classes

struct  dlQ
 

Public Types

enum  respType {
  isBad =0 ,
  isAlert ,
  isData ,
  isStream
}
 
enum  TaskStat {
  isPend =0 ,
  isWrite ,
  isSync ,
  isReady ,
  isDone ,
  isDead
}
 
- Public Types inherited from XrdSsiStream
enum  StreamType {
  isActive = 0 ,
  isPassive
}
 

Public Member Functions

 XrdSsiTaskReal (XrdSsiSessReal *sP)
 
 ~XrdSsiTaskReal ()
 
void Detach (bool force=false)
 
void Finished (XrdSsiRequest &rqstR, const XrdSsiRespInfo &rInfo, bool cancel=false)
 
int ID ()
 
void * Implementation ()
 
void Init (XrdSsiRequest *rP, unsigned short tmo=0)
 
bool Kill ()
 
void PostError ()
 
const char * RequestID ()
 
void SchedError (XrdSsiErrInfo *eInfo=0)
 
void SendError ()
 
bool SendRequest (const char *node)
 
bool SetBuff (XrdSsiErrInfo &eRef, char *buff, int blen)
 
int SetBuff (XrdSsiErrInfo &eRef, char *buff, int blen, bool &last)
 
void SetTaskID (uint32_t tid, uint32_t sid)
 
int XeqEvent (XrdCl::XRootDStatus *status, XrdCl::AnyObject **respP)
 
void XeqEvFin ()
 
- Public Member Functions inherited from XrdSsiEvent
 XrdSsiEvent ()
 
 ~XrdSsiEvent ()
 
void AddEvent (XrdCl::XRootDStatus *st, XrdCl::AnyObject *resp)
 
void ClrEvent ()
 
virtual void DoIt ()
 
virtual void HandleResponse (XrdCl::XRootDStatus *status, XrdCl::AnyObject *response)
 
virtual int XeqEvent (XrdCl::XRootDStatus *st, XrdCl::AnyObject **resp)=0
 
virtual void XeqEvFin ()=0
 
- Public Member Functions inherited from XrdJob
 XrdJob (const char *desc="")
 
virtual ~XrdJob ()
 
virtual void DoIt ()=0
 
- Public Member Functions inherited from XrdCl::ResponseHandler
virtual ~ResponseHandler ()
 
virtual void HandleResponse (XRootDStatus *status, AnyObject *response)
 
virtual void HandleResponseWithHosts (XRootDStatus *status, AnyObject *response, HostList *hostList)
 
- Public Member Functions inherited from XrdSsiResponder
void BindRequest (XrdSsiRequest &rqstR)
 
bool UnBindRequest ()
 
- Public Member Functions inherited from XrdSsiStream
 XrdSsiStream (StreamType stype)
 
virtual ~XrdSsiStream ()
 
virtual BufferGetBuff (XrdSsiErrInfo &eRef, int &dlen, bool &last)
 
virtual bool SetBuff (XrdSsiErrInfo &eRef, char *buff, int blen)
 
virtual int SetBuff (XrdSsiErrInfo &eRef, char *buff, int blen, bool &last)
 
StreamType Type ()
 

Public Attributes

dlQ attList
 
- Public Attributes inherited from XrdJob
const char * Comment
 
XrdJobNextJob
 

Additional Inherited Members

- Static Public Member Functions inherited from XrdCl::ResponseHandler
static ResponseHandlerWrap (std::function< void(XRootDStatus &, AnyObject &)> func)
 
static ResponseHandlerWrap (std::function< void(XRootDStatus *, AnyObject *)> func)
 
- Static Public Attributes inherited from XrdSsiResponder
static const int MaxDirectXfr = 2097152
 
- Protected Types inherited from XrdSsiResponder
enum  Status {
  wasPosted =0 ,
  notPosted ,
  notActive
}
 
- Protected Member Functions inherited from XrdSsiResponder
 XrdSsiResponder ()
 
virtual ~XrdSsiResponder ()
 
void Alert (XrdSsiRespInfoMsg &aMsg)
 
virtual void Finished (XrdSsiRequest &rqstR, const XrdSsiRespInfo &rInfo, bool cancel=false)=0
 
char * GetRequest (int &dlen)
 
void ReleaseRequestBuffer ()
 
Status SetErrResponse (const char *eMsg, int eNum)
 
Status SetMetadata (const char *buff, int blen)
 
Status SetNilResponse ()
 
Status SetResponse (const char *buff, int blen)
 
Status SetResponse (long long fsize, int fdnum)
 
Status SetResponse (XrdSsiStream *strmP)
 
- Protected Attributes inherited from XrdSsiEvent
char tident [24]
 
- Protected Attributes inherited from XrdSsiStream
const StreamType SType
 
- Static Protected Attributes inherited from XrdSsiResponder
static const int MaxMetaDataSZ = 2097152
 2MB metadata limit
 

Detailed Description

Definition at line 43 of file XrdSsiTaskReal.hh.


Class Documentation

◆ XrdSsiTaskReal::dlQ

struct XrdSsiTaskReal::dlQ

Definition at line 103 of file XrdSsiTaskReal.hh.

+ Collaboration diagram for XrdSsiTaskReal::dlQ:
Class Members
XrdSsiTaskReal * next
XrdSsiTaskReal * prev

Member Enumeration Documentation

◆ respType

Enumerator
isBad 
isAlert 
isData 
isStream 

Definition at line 106 of file XrdSsiTaskReal.hh.

◆ TaskStat

Enumerator
isPend 
isWrite 
isSync 
isReady 
isDone 
isDead 

Definition at line 48 of file XrdSsiTaskReal.hh.

Constructor & Destructor Documentation

◆ XrdSsiTaskReal()

XrdSsiTaskReal::XrdSsiTaskReal ( XrdSsiSessReal sP)
inline

Definition at line 95 of file XrdSsiTaskReal.hh.

97 sessP(sP), mdResp(0), wPost(0), tskID(0),
98 defer(0), mhPend(false)
99 {}

◆ ~XrdSsiTaskReal()

XrdSsiTaskReal::~XrdSsiTaskReal ( )
inline

Definition at line 101 of file XrdSsiTaskReal.hh.

101{if (mdResp) delete mdResp;}

Member Function Documentation

◆ Detach()

void XrdSsiTaskReal::Detach ( bool  force = false)

Definition at line 166 of file XrdSsiTaskReal.cc.

167{ tStat = isDead;
168 if (force) sessP = &voidSession;
169}

References isDead.

◆ Finished()

void XrdSsiTaskReal::Finished ( XrdSsiRequest rqstR,
const XrdSsiRespInfo rInfo,
bool  cancel = false 
)
virtual

Notify the responder that a request either completed or was canceled. This allows the responder to release any resources given to the request object (e.g. data response buffer or a stream). This method is invoked when XrdSsiRequest::Finished() is called by the client.

Parameters
rqstRreference to the object describing the request.
rInforeference to the object describing the response.
cancelFalse -> the request/response interaction completed. True -> the request/response interaction aborted because of an error or the client requested that the request be canceled.

Implements XrdSsiResponder.

Definition at line 178 of file XrdSsiTaskReal.cc.

180{
181 EPNAME("TaskFinished");
182 XrdSsiMutexMon rHelp(sessP->MutexP());
183
184// Do some debugging
185//
186 DEBUG("Request="<<&rqstR<<" cancel="<<cancel);
187
188// We should do an unbind here but that is overkill. All we need to do is
189// clear the pointer to the request object.
190//
192
193// If we can kill this task right now, clean up. Otherwise, the message
194// handler will clean things up.
195//
196 if (Kill()) sessP->TaskFinished(this);
197 else {DEBUG("Task removal deferred.");}
198}
#define DEBUG(x)
#define EPNAME(x)
static void ResetResponder(XrdSsiResponder *rP)
XrdSsiMutex * MutexP()
void TaskFinished(XrdSsiTaskReal *tP)

References DEBUG, EPNAME, Kill(), XrdSsiSessReal::MutexP(), XrdSsiRRAgent::ResetResponder(), and XrdSsiSessReal::TaskFinished().

+ Here is the call graph for this function:

◆ ID()

int XrdSsiTaskReal::ID ( )
inline

Definition at line 61 of file XrdSsiTaskReal.hh.

61{return tskID;}

◆ Implementation()

void * XrdSsiTaskReal::Implementation ( )
inline

Definition at line 56 of file XrdSsiTaskReal.hh.

56{return (void *)this;}

◆ Init()

void XrdSsiTaskReal::Init ( XrdSsiRequest rP,
unsigned short  tmo = 0 
)
inline

Definition at line 64 of file XrdSsiTaskReal.hh.

65 {rqstP = rP, tStat = isPend; tmOut = tmo; wPost = 0;
66 mhPend = false; defer = 0;
67 attList.next = attList.prev = this;
68 if (mdResp) {delete mdResp; mdResp = 0;}
69 }
XrdSsiTaskReal * prev
XrdSsiTaskReal * next

References attList, isPend, XrdSsiTaskReal::dlQ::next, and XrdSsiTaskReal::dlQ::prev.

◆ Kill()

bool XrdSsiTaskReal::Kill ( )

Definition at line 276 of file XrdSsiTaskReal.cc.

277{
278 EPNAME("TaskKill");
279 XrdSsiRRInfo rInfo;
280
281// Do some debugging
282//
283 DEBUG("Status="<<statName[tStat]<<" defer=" <<defer<<" mhPend="<<mhPend);
284
285// Affect proper procedure
286//
287 switch(tStat)
288 {case isWrite: break;
289 case isSync: break;
290 case isReady: break;
291 case isDone: tStat = isDead;
292 return !(mhPend || defer);
293 break;
294 case isDead: return !(mhPend || defer);
295 break;
296 case isPend: tStat = isDead;
297 return !(mhPend || defer);
298 break;
299 default: char mBuff[32];
300 snprintf(mBuff, sizeof(mBuff), "%d", tStat);
301 Log.Emsg("TaskKill", "Invalid state", mBuff);
302 tStat = isDead;
303 return false;
304 break;
305 }
306
307// The tricky thing here is that a kill came when we are actully in the process
308// of writing the request. If so, we need to hold until that finished to keep
309// valgring happy (i.e. nt writing from unallocated memory). So, we will have to
310// wait until he write catually occurs before continuing (yech -- thread hung).
311//
312 if (tStat == isWrite && mhPend)
313 {XrdSysSemaphore wSem(0);
314 wPost = &wSem;
315 DEBUG("Waiting for write event.");
316 sessP->UnLock();
317 wSem.Wait();
318 sessP->Lock();
319 }
320
321// If we are here then the request is potentially still active at the server.
322// We will send a synchronous cancel request. It shouldn't take long. Note
323// that, for now, we ignore any errors as we don't have a recovery plan.
324//
325 rInfo.Id(tskID); rInfo.Cmd(XrdSsiRRInfo::Can);
326 DEBUG("Sending cancel request.");
327 XrdCl::XRootDStatus Status = sessP->epFile.Truncate(rInfo.Info(), tmOut);
328
329
330// If we are in the message handler or if we have a message pending, then
331// the message handler will dispose of the task.
332//
333 tStat = isDead;
334 DEBUG("Returning " <<!(mhPend || defer));
335 return !(mhPend || defer);
336}
XRootDStatus Truncate(uint64_t size, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFile.cc:440
unsigned long long Info()
void Cmd(Opc cmd)
void Id(unsigned int id)
XrdCl::File epFile
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
XrdSysError Log

References XrdSsiRRInfo::Can, XrdSsiRRInfo::Cmd(), DEBUG, XrdSysError::Emsg(), XrdSsiSessReal::epFile, EPNAME, XrdSsiRRInfo::Id(), XrdSsiRRInfo::Info(), isDead, isDone, isPend, isReady, isSync, isWrite, XrdSsiSessReal::Lock(), XrdSsi::Log, XrdCl::File::Truncate(), XrdSsiSessReal::UnLock(), and XrdSysSemaphore::Wait().

Referenced by Finished().

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

◆ PostError()

void XrdSsiTaskReal::PostError ( )

◆ RequestID()

const char * XrdSsiTaskReal::RequestID ( )
inline

Definition at line 74 of file XrdSsiTaskReal.hh.

74{return rqstP->GetRequestID();}
const char * GetRequestID()

References XrdSsiRequest::GetRequestID().

+ Here is the call graph for this function:

◆ SchedError()

void XrdSsiTaskReal::SchedError ( XrdSsiErrInfo eInfo = 0)

Definition at line 372 of file XrdSsiTaskReal.cc.

373{
374// Copy the error information if so supplied.
375//
376 if (eInfo) errInfo = *eInfo;
377
378// Schedule the error to avoid lock clashes. Make sure Finished calls deferred.
379// The target (SendError) will decrease the defer refcount (ugly but true).
380//
381 defer++;
382 XrdSsi::schedP->Schedule((XrdJob *)(new SchedEmsg(this)));
383}
void Schedule(XrdJob *jp)
XrdScheduler * schedP

References XrdSsi::schedP, and XrdScheduler::Schedule().

Referenced by SendRequest(), and XrdSsiSessReal::XeqEvent().

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

◆ SendError()

void XrdSsiTaskReal::SendError ( )

Definition at line 389 of file XrdSsiTaskReal.cc.

390{
391 EPNAME("SendError");
392
393// Lock the associated session
394//
395 sessP->Lock();
396 DEBUG("Status="<<statName[tStat]<<" defer=" <<defer<<" mhPend="<<mhPend);
397
398// If there was no call to finished then we need to send an error response
399// which may precipitate a finished call now or later. Defer should be set
400// with anticipation that we will decrease it after the callback.
401//
402 if (tStat != isDead)
403 {int eNum;
404 const char *eTxt = errInfo.Get(eNum).c_str();
405 sessP->UnLock();
406 SetErrResponse(eTxt, eNum);
407 sessP->Lock();
408 defer--;
409 if (tStat != isDead)
410 {sessP->UnLock();
411 return;
412 }
413 }
414
415// If it is safe to do so, finish up everything here
416//
417
418 if (mhPend || defer)
419 {DEBUG("Defering TaskFinished."<<" defer=" <<defer<<" mhPend="<<mhPend);
420 sessP->UnLock();
421 } else {
422 DEBUG("Calling TaskFinished");
423 sessP->UnLock();
424 sessP->TaskFinished(this);
425 }
426}
const std::string & Get(int &eNum) const
Status SetErrResponse(const char *eMsg, int eNum)

References DEBUG, EPNAME, XrdSsiErrInfo::Get(), isDead, XrdSsiSessReal::Lock(), XrdSsiResponder::SetErrResponse(), XrdSsiSessReal::TaskFinished(), and XrdSsiSessReal::UnLock().

+ Here is the call graph for this function:

◆ SendRequest()

bool XrdSsiTaskReal::SendRequest ( const char *  node)

Definition at line 434 of file XrdSsiTaskReal.cc.

435{
437 XrdSsiRRInfo rrInfo;
438 char *reqBuff;
439 int reqBlen;
440
441// We must be in pend state to send a request. If we are not then the request
442// must have been cancelled. It also means we have a logic error if the
443// state is not isDead as we can't finish off the task and leak memory.
444//
445 if (tStat != isPend)
446 {if (tStat == isDead) sessP->TaskFinished(this);
447 else Log.Emsg("SendRequest", "Invalid state", statName[tStat],
448 "; should be isPend!");
449 return false;
450 }
451
452// Establish the endpoint
453//
455
456// Get the request information. Make sure to defer Finish() calls.
457//
458 defer++;
459 reqBuff = XrdSsiRRAgent::Request(this)->GetRequest(reqBlen);
460 defer--;
461
462// It's possible that GetRequest() called finished so process that here.
463//
464 if (tStat == isDead)
465 {sessP->TaskFinished(this);
466 return false;
467 }
468
469
470// Construct the info for this request
471//
472 rrInfo.Id(tskID);
473 rrInfo.Size(reqBlen);
474 tStat = isWrite;
475
476// If we are writing a zero length message, we must fake a request as zero
477// zero length messages are normally deep-sixed.
478//
479 if (!reqBlen)
480 {reqBuff = &zedData;
481 reqBlen = 1;
482 }
483
484// Issue the write
485//
486 Status = sessP->epFile.Write(rrInfo.Info(), (uint32_t)reqBlen, reqBuff,
487 (XrdCl::ResponseHandler *)this, tmOut);
488
489// Determine ending status. If it's bad, schedule an error. Note that calls to
490// Finished() will be deferred until the error thread gets control.
491//
492 if (!Status.IsOK())
493 {XrdSsiUtils::SetErr(Status, errInfo);
494 SchedError();
495 return false;
496 }
497
498// Indicate a message handler call outstanding
499//
500 mhPend = true;
501 return true;
502}
XRootDStatus Write(uint64_t offset, uint32_t size, const void *buffer, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFile.cc:286
Handle an async response.
static XrdSsiRequest * Request(XrdSsiResponder *rP)
static void SetNode(XrdSsiRequest *rP, const char *name)
void Size(unsigned int sz)
virtual char * GetRequest(int &dlen)=0
void SchedError(XrdSsiErrInfo *eInfo=0)
static void SetErr(XrdCl::XRootDStatus &Status, XrdSsiErrInfo &eInfo)

References XrdSysError::Emsg(), XrdSsiSessReal::epFile, XrdSsiRequest::GetRequest(), XrdSsiRRInfo::Id(), XrdSsiRRInfo::Info(), isDead, isPend, isWrite, XrdSsi::Log, XrdSsiRRAgent::Request(), SchedError(), XrdSsiUtils::SetErr(), XrdSsiRRAgent::SetNode(), XrdSsiRRInfo::Size(), XrdSsiSessReal::TaskFinished(), and XrdCl::File::Write().

Referenced by XrdSsiSessReal::Run(), and XrdSsiSessReal::XeqEvent().

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

◆ SetBuff() [1/2]

bool XrdSsiTaskReal::SetBuff ( XrdSsiErrInfo eRef,
char *  buff,
int  blen 
)
virtual

Asynchronously obtain data from a passive stream (client-side only).

Parameters
eRefreference to where error information is to be placed for encountered before during the stream initiation. When data is ready for processing, the ProcessResponseData() callback is called on the request associated with this stream. Also see XrdSsiRequest::GetResponseData() helper method.
buffpointer to the buffer to receive the data. The buffer must remain valid until ProcessResponse() is called.
blenthe length of the buffer (i.e. maximum that can be returned).
Returns
true The stream has been successfully scheduled to return the data.
false The stream could not be scheduled; eRef holds the reason.

Reimplemented from XrdSsiStream.

Definition at line 549 of file XrdSsiTaskReal.cc.

550{
551 EPNAME("TaskSetBuff");
552 XrdSsiMutexMon rHelp(sessP->MutexP());
553 XrdCl::XRootDStatus epStatus;
554 XrdSsiRRInfo rrInfo;
555
556// Check if this is a proper call or we have reached EOF
557//
558 DEBUG("ReadAsync Status=" <<statName[tStat]);
559 if (tStat != isReady)
560 {eRef.Set("Stream is not active", ENODEV);
561 return false;
562 }
563
564// We only support (for now) one read at a time
565//
566 if (mhPend)
567 {eRef.Set("Stream is already active", EINPROGRESS);
568 return false;
569 }
570
571// Make sure the buffer length is valid
572//
573 if (blen <= 0)
574 {eRef.Set("Buffer length invalid", EINVAL);
575 return false;
576 }
577
578// Prepare to issue the read
579//
580 rrInfo.Id(tskID);
581
582// Issue a read
583//
584 dataBuff = buff; dataRlen = blen;
585 epStatus = sessP->epFile.Read(rrInfo.Info(), (uint32_t)blen, buff,
586 (XrdCl::ResponseHandler *)this, tmOut);
587
588// If success then indicate we are pending and return
589//
590 if (epStatus.IsOK()) {mhPend = true; return true;}
591
592// We failed, return an error
593//
594 XrdSsiUtils::SetErr(epStatus, eRef);
595 tStat = isDone;
596 DEBUG("ReadAsync error; " <<epStatus.ToStr());
597 return false;
598}
XRootDStatus Read(uint64_t offset, uint32_t size, void *buffer, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFile.cc:206
std::string ToStr() const
Convert to string.
void Set(const char *eMsg=0, int eNum=0, int eArg=0)
bool IsOK() const
We're fine.

References DEBUG, XrdSsiSessReal::epFile, EPNAME, XrdSsiRRInfo::Id(), XrdSsiRRInfo::Info(), isDone, XrdCl::Status::IsOK(), isReady, XrdSsiSessReal::MutexP(), XrdCl::File::Read(), XrdSsiErrInfo::Set(), XrdSsiUtils::SetErr(), and XrdCl::XRootDStatus::ToStr().

+ Here is the call graph for this function:

◆ SetBuff() [2/2]

int XrdSsiTaskReal::SetBuff ( XrdSsiErrInfo eRef,
char *  buff,
int  blen,
bool &  last 
)
virtual

Synchronously obtain data from a passive stream (client- or server-side).

Parameters
eRefThe object to receive any error description.
buffpointer to the buffer to receive the data. request object is notified that the operation completed.
blenthe length of the buffer (i.e. maximum that can be returned).
lastinput: should be set to false. output: if true it indicates that no more data remains to be returned either for this call or on the next call.
Returns
>0 The number of bytes placed in buff.
=0 No more data remains and the stream becomes invalid.
<0 Fatal error occurred; eRef holds the reason.

Reimplemented from XrdSsiStream.

Definition at line 508 of file XrdSsiTaskReal.cc.

510{
511 EPNAME("TaskSetBuff");
512 XrdSsiMutexMon rHelp(sessP->MutexP());
513 XrdCl::XRootDStatus epStatus;
514 XrdSsiRRInfo rrInfo;
515 union {uint32_t ubRead; int ibRead;};
516
517// Check if this is a proper call or we have reached EOF
518//
519 DEBUG("ReadSync status=" <<statName[tStat]);
520 if (tStat != isReady)
521 {if (tStat == isDone) return 0;
522 eRef.Set("Stream is not active", ENODEV);
523 return -1;
524 }
525
526// Prepare to issue the read
527//
528 rrInfo.Id(tskID);
529
530// Issue a read
531//
532 epStatus = sessP->epFile.Read(rrInfo.Info(),(uint32_t)blen,buff,ubRead,tmOut);
533 if (epStatus.IsOK())
534 {if (ibRead < blen) {tStat = isDone; last = true;}
535 DEBUG("ReadSync returning " <<ibRead <<" bytes.");
536 return ibRead;
537 }
538
539// We failed, return an error
540//
541 XrdSsiUtils::SetErr(epStatus, eRef);
542 tStat = isDone;
543 DEBUG("ReadSync error; " <<epStatus.ToStr());
544 return -1;
545}

References DEBUG, XrdSsiSessReal::epFile, EPNAME, XrdSsiRRInfo::Id(), XrdSsiRRInfo::Info(), isDone, XrdCl::Status::IsOK(), isReady, XrdSsiSessReal::MutexP(), XrdCl::File::Read(), XrdSsiErrInfo::Set(), XrdSsiUtils::SetErr(), and XrdCl::XRootDStatus::ToStr().

+ Here is the call graph for this function:

◆ SetTaskID()

void XrdSsiTaskReal::SetTaskID ( uint32_t  tid,
uint32_t  sid 
)
inline

Definition at line 86 of file XrdSsiTaskReal.hh.

87 {tskID = tid;
88 snprintf(tident, sizeof(tident), "T %u#%u", sid, tid);
89 }
char tident[24]

References XrdSsiEvent::tident.

◆ XeqEvent()

int XrdSsiTaskReal::XeqEvent ( XrdCl::XRootDStatus status,
XrdCl::AnyObject **  respP 
)
virtual

Implements XrdSsiEvent.

Definition at line 604 of file XrdSsiTaskReal.cc.

606{
607 EPNAME("TaskXeqEvent");
608
609 XrdCl::AnyObject *response = *respP;
610 XrdSsiRespInfoMsg *aMsg;
611 char *dBuff;
612 union {uint32_t ubRead; int ibRead;};
613 int dLen;
614 TaskStat Tstat;
615 bool last, aOK = status->IsOK();
616
617// Obtain a lock and indicate the any Finish() calls should be deferred until
618// we return from this method. The reason is that any callback that we do here
619// may precipitate a Finish() call not to mention some other thread doing so.
620//
621 XrdSsiMutexMon monMtx(sessP->MutexP());
622 defer++;
623 mhPend = false;
624
625// Do some debugging
626//
627 DEBUG("aOK="<<aOK<<" status="<<statName[tStat]<<" defer=" <<defer);
628
629// Affect proper response
630//
631 switch(tStat)
632 {case isWrite:
633 if (!aOK)
634 {RespErr(status); // Unlocks the mutex!
635 monMtx.Reset();
636 return 1;
637 }
638 DEBUG("Write completed.");
639 if (wPost)
640 {DEBUG("Posting killer.");
641 wPost->Post(); wPost = 0;
642 return 1;
643 }
644 DEBUG("Calling RelBuff.");
646 if (tStat == isWrite)
647 {monMtx.Reset();
648 return (Ask4Resp() ? 0 : 1); // Unlocks the mutex!
649 }
650 return 1;
651
652 case isSync:
653 monMtx.Reset();
654 if (!aOK) return (RespErr(status) ? 0 : 1); // Unlocks the mutex!
655
656 if (response) switch(GetResp(respP, dBuff, dLen))
657 {case isAlert: aMsg = new AlertMsg(*respP, dBuff, dLen);
658 *respP = 0;
659 sessP->UnLock();
660 XrdSsiRRAgent::Alert(*rqstP, *aMsg);
661 sessP->Lock();
662 if (tStat == isSync)
663 return (Ask4Resp() ? 0 : 1);
664 Tstat = tStat;
665 sessP->UnLock();
666 return (Tstat != isDead ? 0 : 1);
667 break;
668 case isData: tStat = isDone; sessP->UnLock();
669 SetResponse(dBuff, dLen);
670 break;
671 case isStream: tStat = isReady; sessP->UnLock();
672 SetResponse((XrdSsiStream *)this);
673 break;
674 default: tStat = isDone; sessP->UnLock();
675 SetErrResponse("Invalid response", EFAULT);
676 break;
677 } else {
678 tStat = isDone; sessP->UnLock();
679 SetErrResponse("Missing response", EFAULT);
680 }
681 return 0;
682
683 case isReady:
684 break;
685
686 case isDead:
687 return 1;
688
689 default: char mBuff[32];
690 snprintf(mBuff, sizeof(mBuff), "%d", tStat);
691 Log.Emsg("TaskXeqEvent", "Invalid state", mBuff);
692 return 1;
693 }
694
695// Handle incoming response data. The session mutex is still locked!
696//
697 if (!aOK || !response)
698 {ibRead = -1;
699 if (!aOK) XrdSsiUtils::SetErr(*status, XrdSsiRRAgent::ErrInfoRef(rqstP));
700 else XrdSsiRRAgent::ErrInfoRef(rqstP).Set("Missing response", EFAULT);
701 } else {
702 XrdCl::ChunkInfo *cInfo = 0;
703 response->Get(cInfo);
704 ubRead = (cInfo ? cInfo->length : 0);
705 }
706
707// Reflect the response to the request as this was an async receive. We may not
708// reference this object after the UnLock() as Finished() might be called.
709//
710 if (ibRead < dataRlen) {tStat = isDone; dataRlen = ibRead;}
711 dBuff = dataBuff;
712 last = tStat == isDone;
713 sessP->UnLock();
714 DEBUG("Calling ProcessResponseData; len="<<ibRead<<" last="<<last);
716 dBuff, ibRead, last);
717
718// All done
719//
720 return 0;
721}
void Get(Type &object)
Retrieve the object being held.
static void Alert(XrdSsiRequest &reqR, XrdSsiRespInfoMsg &aMsg)
static XrdSsiErrInfo & ErrInfoRef(XrdSsiRequest *rP)
virtual void ProcessResponseData(const XrdSsiErrInfo &eInfo, char *buff, int blen, bool last)
Status SetResponse(const char *buff, int blen)
Describe a data chunk for vector read.
uint32_t length
offset in the file

References XrdSsiRRAgent::Alert(), DEBUG, XrdSysError::Emsg(), EPNAME, XrdSsiRRAgent::ErrInfoRef(), XrdCl::AnyObject::Get(), isAlert, isData, isDead, isDone, XrdCl::Status::IsOK(), isReady, isStream, isSync, isWrite, XrdCl::ChunkInfo::length, XrdSsiSessReal::Lock(), XrdSsi::Log, XrdSsiSessReal::MutexP(), XrdSysSemaphore::Post(), XrdSsiRequest::ProcessResponseData(), XrdSsiResponder::ReleaseRequestBuffer(), XrdSsiMutexMon::Reset(), XrdSsiErrInfo::Set(), XrdSsiUtils::SetErr(), XrdSsiResponder::SetErrResponse(), XrdSsiResponder::SetResponse(), and XrdSsiSessReal::UnLock().

+ Here is the call graph for this function:

◆ XeqEvFin()

void XrdSsiTaskReal::XeqEvFin ( )
virtual

Implements XrdSsiEvent.

Definition at line 727 of file XrdSsiTaskReal.cc.

728{
729 EPNAME("TaskXeqEvFin");
730
731// Obtain a lock and remove defer flag (protected by the lock)
732//
733 sessP->Lock();
734 defer--;
735 DEBUG("Status="<<statName[tStat]<<" defer=" <<defer<<" mhPend="<<mhPend);
736
737
738// Check if finished has been called while we were deferred or if this is an
739// orphaned task due to a session stop request.
740//
741 if (tStat == isDead)
742 {if (sessP != &voidSession)
743 {if (mhPend || defer) {DEBUG("Defering TaskFinished.");}
744 else {DEBUG("Calling TaskFinished");
745 sessP->UnLock();
746 sessP->TaskFinished(this);
747 }
748 } else {
749 DEBUG("Deleting orphaned task.");
750 sessP->UnLock();
751 delete this;
752 }
753 } else sessP->UnLock();
754}

References DEBUG, EPNAME, isDead, XrdSsiSessReal::Lock(), XrdSsiSessReal::TaskFinished(), and XrdSsiSessReal::UnLock().

+ Here is the call graph for this function:

Member Data Documentation

◆ attList

dlQ XrdSsiTaskReal::attList

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