XRootD
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)
 
- Public Member Functions inherited from XrdJob
 XrdJob (const char *desc="")
 
virtual ~XrdJob ()
 
- Public Member Functions inherited from XrdCl::ResponseHandler
virtual ~ResponseHandler ()
 
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)
 
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)
 
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 More...
 

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  {}
XrdSsiStream(StreamType stype)

◆ ~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 }

◆ 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)
Definition: XrdBwmTrace.hh:54
#define EPNAME(x)
Definition: XrdBwmTrace.hh:56
static void ResetResponder(XrdSsiResponder *rP)
XrdSsiMutex * MutexP()
void TaskFinished(XrdSsiTaskReal *tP)

References DEBUG, EPNAME, and XrdSsiRRAgent::ResetResponder().

+ 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()
Definition: XrdSsiRRInfo.hh:64
void Cmd(Opc cmd)
Definition: XrdSsiRRInfo.hh:45
void Id(unsigned int id)
Definition: XrdSsiRRInfo.hh:52
XrdCl::File epFile
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 XrdSsiRRInfo::Can, XrdSsiRRInfo::Cmd(), DEBUG, XrdSysError::Emsg(), EPNAME, XrdSsiRRInfo::Id(), XrdSsiRRInfo::Info(), XrdSsi::Log, and XrdSysSemaphore::Wait().

+ Here is the call 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 }
Definition: XrdJob.hh:43
void Schedule(XrdJob *jp)
XrdScheduler * schedP
Definition: XrdSsiClient.cc:74

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

Referenced by 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, and EPNAME.

◆ 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)
Definition: XrdSsiRRInfo.hh:60
virtual char * GetRequest(int &dlen)=0
void SchedError(XrdSsiErrInfo *eInfo=0)
static void SetErr(XrdCl::XRootDStatus &Status, XrdSsiErrInfo &eInfo)
Definition: XrdSsiUtils.cc:232

References XrdSysError::Emsg(), XrdSsiRequest::GetRequest(), XrdSsiRRInfo::Id(), XrdSsiRRInfo::Info(), XrdSsi::Log, XrdSsiRRAgent::Request(), XrdSsiUtils::SetErr(), XrdSsiRRAgent::SetNode(), and XrdSsiRRInfo::Size().

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.
Definition: XrdClStatus.hh:124

References DEBUG, EPNAME, XrdSsiRRInfo::Id(), XrdSsiRRInfo::Info(), XrdCl::Status::IsOK(), 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, EPNAME, XrdSsiRRInfo::Id(), XrdSsiRRInfo::Info(), XrdCl::Status::IsOK(), 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]
Definition: XrdSsiEvent.hh:62

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 XrdSsiErrInfo & ErrInfoRef(XrdSsiRequest *rP)
static void Alert(XrdSsiRequest &reqR, XrdSsiRespInfoMsg &aMsg)
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(), XrdCl::Status::IsOK(), XrdCl::ChunkInfo::length, XrdSsi::Log, XrdSsiMutexMon::Reset(), XrdSsiErrInfo::Set(), and XrdSsiUtils::SetErr().

+ 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, and EPNAME.

Member Data Documentation

◆ attList

dlQ XrdSsiTaskReal::attList

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