/******************************************************************************/ /* */ /* 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; }