Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-01-08 10:33:34

0001 #ifndef __XRDSSIRESPONDER_HH__
0002 #define __XRDSSIRESPONDER_HH__
0003 /******************************************************************************/
0004 /*                                                                            */
0005 /*                    X r d S s i R e s p o n d e r . h h                     */
0006 /*                                                                            */
0007 /* (c) 2013 by the Board of Trustees of the Leland Stanford, Jr., University  */
0008 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
0009 /*              DE-AC02-76-SFO0515 with the Department of Energy              */
0010 /*                                                                            */
0011 /* This file is part of the XRootD software suite.                            */
0012 /*                                                                            */
0013 /* XRootD is free software: you can redistribute it and/or modify it under    */
0014 /* the terms of the GNU Lesser General Public License as published by the     */
0015 /* Free Software Foundation, either version 3 of the License, or (at your     */
0016 /* option) any later version.                                                 */
0017 /*                                                                            */
0018 /* XRootD is distributed in the hope that it will be useful, but WITHOUT      */
0019 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or      */
0020 /* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public       */
0021 /* License for more details.                                                  */
0022 /*                                                                            */
0023 /* You should have received a copy of the GNU Lesser General Public License   */
0024 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file  */
0025 /* COPYING (GPL license).  If not, see <http://www.gnu.org/licenses/>.        */
0026 /*                                                                            */
0027 /* The copyright holder's institutional names and contributor's names may not */
0028 /* be used to endorse or promote products derived from this software without  */
0029 /* specific prior written permission of the institution or contributor.       */
0030 /******************************************************************************/
0031 
0032 #include <cstdlib>
0033 #include <cstring>
0034 
0035 #include "XrdSsi/XrdSsiRequest.hh"
0036 
0037 //-----------------------------------------------------------------------------
0038 //! The XrdSsiResponder.hh class provides a request processing object a way to
0039 //! respond to a request. It is a companion (friend) class of XrdSsiRequest.
0040 //! This class is only practically meaningful server-side.
0041 //!
0042 //! Any class that needs to post a response, release a request buffer or post
0043 //! stream data to the request object should inherit this class and use its
0044 //! methods to get access to the request object. Typically, a task class that
0045 //! is created by XrdSsiService::Execute() to handle the request would inherit
0046 //! this class so it can respond. The object that wants to post a response must
0047 //! first call BindRequest() to establish the request-responder association.
0048 //!
0049 //! When the XrdSsiResponder::SetResponse() method is called to post a response
0050 //! the request object's ProcessResponse() method is called. Ownership of the
0051 //! request object does not revert back to the object's creator until the
0052 //! XrdSsiRequest::Finished() method returns. That method first calls
0053 //! XrdSsiResponder::Finished() to break the request-responder association and
0054 //! reclaim any response data buffer or stream resource before it gives up
0055 //! control of the request object. This means you must provide an implementation
0056 //! To the Finished() method defined here.
0057 //!
0058 //! Once Finished() is called you must call UnBindRequest() when you are
0059 //! actually through referencing the request object. While that is true most
0060 //! of the time, it may not be so when an async cancellation occurs (i.e.
0061 //! you may need to defer release of the request object). Note that should
0062 //! you delete this object before calling UnBindRequest(), the responder
0063 //! object is forcibly unbound from the request.
0064 //-----------------------------------------------------------------------------
0065 
0066 class XrdSsiStream;
0067 
0068 class XrdSsiResponder
0069 {
0070 public:
0071 friend class XrdSsiRequest;
0072 friend class XrdSsiRRAgent;
0073 
0074 //-----------------------------------------------------------------------------
0075 //! The maximum amount of metadata+data (i.e. the sum of two blen arguments in
0076 //! SetMetadata() and and SetResponse(const char *buff, int blen), respectively)
0077 //! that may be directly sent to the client without the SSI framework converting
0078 //! the data buffer response into a stream response.
0079 //-----------------------------------------------------------------------------
0080 
0081 static const int MaxDirectXfr = 2097152; //< Max (metadata+data) direct xfr
0082 
0083 //-----------------------------------------------------------------------------
0084 //! Take ownership of a request object by binding the request object to a
0085 //! responder object. This method must be called by the responder before
0086 //! posting any responses.
0087 //!
0088 //! @param  rqstR reference to the request object.
0089 //-----------------------------------------------------------------------------
0090 
0091         void    BindRequest(XrdSsiRequest   &rqstR);
0092 
0093 //-----------------------------------------------------------------------------
0094 //! Unbind this responder from the request object it is bound to. Upon return
0095 //! ownership of the associated request object reverts back to the creator of
0096 //! the object who is responsible for deleting or recycling the request object.
0097 //! UnBindRequest() is also called when the responder object is deleted.
0098 //!
0099 //! @return true  Request successfully unbound.
0100 //!         false UnBindRequest already called or called prior to Finish().
0101 //-----------------------------------------------------------------------------
0102 
0103         bool    UnBindRequest();
0104 
0105 protected:
0106 
0107 //-----------------------------------------------------------------------------
0108 //! Send an alert message to the request. This is a convenience method that
0109 //! avoids race conditions with Finished() so it is safe to use in all cases.
0110 //! This is a server-side call. The service is responsible for creating a
0111 //! RespInfoMsg object containing the message and supplying a RecycleMsg() method.
0112 //!
0113 //! @param  aMsg  reference to the message to be sent.
0114 //-----------------------------------------------------------------------------
0115 
0116         void   Alert(XrdSsiRespInfoMsg &aMsg);
0117 
0118 //-----------------------------------------------------------------------------
0119 //! Notify the responder that a request either completed or was canceled. This
0120 //! allows the responder to release any resources given to the request object
0121 //! (e.g. data response buffer or a stream). This method is invoked when
0122 //! XrdSsiRequest::Finished() is called by the client.
0123 //!
0124 //! @param  rqstR  reference to the object describing the request.
0125 //! @param  rInfo  reference to the object describing the response.
0126 //! @param  cancel False -> the request/response interaction completed.
0127 //!                True  -> the request/response interaction aborted because
0128 //!                         of an error or the client requested that the
0129 //!                         request be canceled.
0130 //-----------------------------------------------------------------------------
0131 
0132 virtual void   Finished(      XrdSsiRequest  &rqstR,
0133                         const XrdSsiRespInfo &rInfo,
0134                               bool            cancel=false) = 0;
0135 
0136 //-----------------------------------------------------------------------------
0137 //! Obtain the request data sent by a client.
0138 //!
0139 //! Note: This method is called with the object's recursive mutex unlocked!
0140 //!
0141 //! @param  dlen  holds the length of the request after the call.
0142 //!
0143 //! @return =0    No request data available, dlen has been set to zero.
0144 //! @return !0    Pointer to the buffer holding the request, dlen has the length
0145 //-----------------------------------------------------------------------------
0146 
0147         char  *GetRequest(int &dlen);
0148 
0149 //-----------------------------------------------------------------------------
0150 //! Release the request buffer of the request bound to this object. This method
0151 //! duplicates the protected method of the same name in XrdSsiRequest and exists
0152 //! here for calling safety and consistency relative to the responder.
0153 //-----------------------------------------------------------------------------
0154 
0155         void   ReleaseRequestBuffer();
0156 
0157 //-----------------------------------------------------------------------------
0158 //! The following enums are returned by SetMetadata() and SetResponse() to
0159 //!  indicate ending status.
0160 //-----------------------------------------------------------------------------
0161 
0162 enum Status {wasPosted=0, //!< Success: The response was successfully posted
0163              notPosted,   //!< Failure: A request was not bound to this object
0164                           //!<          or a response has already been posted
0165                           //!<          or the metadata length was invalid
0166              notActive    //!< Failure: Request is no longer active
0167             };
0168 
0169 //-----------------------------------------------------------------------------
0170 //! Set a pointer to metadata to be sent out-of-band ahead of the response.
0171 //!
0172 //! @param  buff  pointer to a buffer holding the metadata. The buffer must
0173 //!               remain valid until XrdSsiResponder::Finished() is called.
0174 //! @param  blen  the length of the metadata in buff that is to be sent. It must
0175 //!               in the range 0 <= blen <= MaxMetaDataSZ.
0176 //!
0177 //! @return       See Status enum for possible values.
0178 //-----------------------------------------------------------------------------
0179 
0180 static const int MaxMetaDataSZ = 2097152; //!< 2MB metadata limit
0181 
0182        Status  SetMetadata(const char *buff, int blen);
0183 
0184 //-----------------------------------------------------------------------------
0185 //! Set an error response for a request.
0186 //!
0187 //! @param  eMsg  the message describing the error. The message is copied to
0188 //!               private storage.
0189 //! @param  eNum  the errno associated with the error.
0190 //!
0191 //! @return       See Status enum for possible values.
0192 //-----------------------------------------------------------------------------
0193 
0194        Status  SetErrResponse(const char *eMsg, int eNum);
0195 
0196 //-----------------------------------------------------------------------------
0197 //! Set a nil response for a request (used for sending only metadata).
0198 //!
0199 //! @return       See Status enum for possible values.
0200 //-----------------------------------------------------------------------------
0201 
0202 inline Status  SetNilResponse() {return SetResponse((const char *)0,0);}
0203 
0204 //-----------------------------------------------------------------------------
0205 //! Set a memory buffer containing data as the request response.
0206 //!
0207 //! @param  buff  pointer to a buffer holding the response. The buffer must
0208 //!               remain valid until XrdSsiResponder::Finished() is called.
0209 //! @param  blen  the length of the response in buff that is to be sent.
0210 //!
0211 //! @return       See Status enum for possible values.
0212 //-----------------------------------------------------------------------------
0213 
0214        Status  SetResponse(const char *buff, int blen);
0215 
0216 //-----------------------------------------------------------------------------
0217 //! Set a file containing data as the response.
0218 //!
0219 //! @param  fsize the size of the file containing the response.
0220 //! @param  fdnum the file descriptor of the open file.
0221 //!
0222 //! @return       See Status enum for possible values.
0223 //-----------------------------------------------------------------------------
0224 
0225        Status  SetResponse(long long fsize, int fdnum);
0226 
0227 //-----------------------------------------------------------------------------
0228 //! Set a stream object that is to provide data as the response.
0229 //!
0230 //! @param  strmP pointer to stream object that is to be used to supply response
0231 //!               data. See XrdSsiStream for more details.
0232 //!
0233 //! @return       See Status enum for possible values.
0234 //-----------------------------------------------------------------------------
0235 
0236        Status  SetResponse(XrdSsiStream *strmP);
0237 
0238 //-----------------------------------------------------------------------------
0239 //! This class is meant to be inherited by an object that will actually posts
0240 //! responses.
0241 //-----------------------------------------------------------------------------
0242 
0243                XrdSsiResponder();
0244 
0245 //-----------------------------------------------------------------------------
0246 //! Destructor is protected. You cannot use delete on a responder object, as it
0247 //! is meant to be inherited by a class and not separately instantiated.
0248 //-----------------------------------------------------------------------------
0249 
0250 protected:
0251 
0252 virtual       ~XrdSsiResponder();
0253 
0254 private:
0255 
0256 // The spMutex protects the reqP pointer. It is a hiearchical mutex in that it
0257 // may be obtained prior to obtaining the mutex protecting the request without
0258 // fear of a deadlock (the reverse is not possible). If reqP is zero then
0259 // this responder is not bound to a request.
0260 //
0261 XrdSsiMutex    spMutex;
0262 XrdSsiRequest *reqP;
0263 long long      rsvd1; // Reserved fields for extensions with ABI compliance
0264 long long      rsvd2;
0265 long long      rsvd3;
0266 };
0267 #endif