/******************************************************************************/
/* */
/* X r d S s i A l e r t . c c */
/* */
/* (c) 2017 by the Board of Trustees of the Leland Stanford, Jr., University */
/* All Rights Reserved */
/* Produced by Andrew Hanushevsky for Stanford University under contract */
/* DE-AC02-76-SFO0515 with the Department of Energy */
/* */
/* This file is part of the XRootD software suite. */
/* */
/* XRootD is free software: you can redistribute it and/or modify it under */
/* the terms of the GNU Lesser General Public License as published by the */
/* Free Software Foundation, either version 3 of the License, or (at your */
/* option) any later version. */
/* */
/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
/* License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
/* COPYING (GPL license). If not, see . */
/* */
/* The copyright holder's institutional names and contributor's names may not */
/* be used to endorse or promote products derived from this software without */
/* specific prior written permission of the institution or contributor. */
/******************************************************************************/
#include
#include
#include
#include "XrdOuc/XrdOucErrInfo.hh"
#include "XrdSsi/XrdSsiAlert.hh"
#include "XrdSsi/XrdSsiRRInfo.hh"
/******************************************************************************/
/* S t a t i c s */
/******************************************************************************/
XrdSysMutex XrdSsiAlert::aMutex;
XrdSsiAlert *XrdSsiAlert::free = 0;
int XrdSsiAlert::fNum = 0;
int XrdSsiAlert::fMax = XrdSsiAlert::fmaxDflt;
/******************************************************************************/
/* A l l o c */
/******************************************************************************/
XrdSsiAlert *XrdSsiAlert::Alloc(XrdSsiRespInfoMsg &aMsg)
{
XrdSsiAlert *aP;
// Obtain a lock
//
aMutex.Lock();
// Allocate via stack or a new call
//
if (!(aP = free)) aP = new XrdSsiAlert();
else {free = aP->next; fNum--;}
// Unlock mutex
//
aMutex.UnLock();
// Fill out object and return it
//
aP->next = 0;
aP->theMsg = &aMsg;
return aP;
}
/******************************************************************************/
/* D o n e */
/******************************************************************************/
// Gets invoked only after query() on wtresp signal was sent
void XrdSsiAlert::Done(int &retc, XrdOucErrInfo *eiP, const char *name)
{
// This is an async callback so we need to delete our errinfo object.
//
delete eiP;
// Simply recycle this object.
//
Recycle();
}
/******************************************************************************/
/* R e c y c l e */
/******************************************************************************/
void XrdSsiAlert::Recycle()
{
// Issue callback to release the message if we have one
//
if (theMsg) theMsg->RecycleMsg();
// Place object on the queue unless we have too many
//
aMutex.Lock();
if (fNum >= fMax) delete this;
else {next = free; free = this; fNum++;}
aMutex.UnLock();
}
/******************************************************************************/
/* S e t I n f o */
/******************************************************************************/
int XrdSsiAlert::SetInfo(XrdOucErrInfo &eInfo, char *aMsg, int aLen)
{
static const int aIovSz = 3;
struct AlrtResp {struct iovec ioV[aIovSz]; XrdSsiRRInfoAttn aHdr;};
AlrtResp *alrtResp;
char *mBuff, *aData;
int n;
// We will be constructing the response in the message buffer. This is
// gauranteed to be big enough for our purposes so no need to check the size.
//
mBuff = eInfo.getMsgBuff(n);
// Initialize the response
//
alrtResp = (AlrtResp *)mBuff;
memset(alrtResp, 0, sizeof(AlrtResp));
alrtResp->aHdr.pfxLen = htons(sizeof(XrdSsiRRInfoAttn));
// Fill out iovec to point to our header
//
// alrtResp->ioV[0].iov_len = sizeof(XrdSsiRRInfoAttn) + msgBlen;
alrtResp->ioV[1].iov_base = mBuff+offsetof(struct AlrtResp, aHdr);
alrtResp->ioV[1].iov_len = sizeof(XrdSsiRRInfoAttn);
// Fill out the iovec for the alert data
//
aData = theMsg->GetMsg(n);
alrtResp->ioV[2].iov_base = aData;
alrtResp->ioV[2].iov_len = n;
alrtResp->aHdr.mdLen = htonl(n);
alrtResp->aHdr.tag = XrdSsiRRInfoAttn::alrtResp;
// Return up to 8 bytes of alert data for debugging purposes
//
if (aMsg) memcpy(aMsg, aData, (n < (int)sizeof(aMsg) ? n : 8));
// Setup to have metadata actually sent to the requestor
//
eInfo.setErrCode(aIovSz);
return n;
}