XrdCmsClientMsg.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                    X r d C m s C l i e n t M s g . c c                     */
00004 /*                                                                            */
00005 /* (c) 2007 by the Board of Trustees of the Leland Stanford, Jr., University  */
00006 /*                            All Rights Reserved                             */
00007 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00008 /*              DE-AC02-76-SFO0515 with the Department of Energy              */
00009 /******************************************************************************/
00010 
00011 //          $Id: XrdCmsClientMsg.cc 38011 2011-02-08 18:35:57Z ganis $
00012 
00013 // Vased on: XrdCmsClientMsg.cc,v 1.14 2006/09/26 07:49:14 abh
00014 
00015 const char *XrdCmsClientMsgCVSID = "$Id: XrdCmsClientMsg.cc 38011 2011-02-08 18:35:57Z ganis $";
00016 
00017 #include <stdlib.h>
00018   
00019 #include "XProtocol/YProtocol.hh"
00020 #include "XrdCms/XrdCmsClientMsg.hh"
00021 #include "XrdCms/XrdCmsParser.hh"
00022 #include "XrdCms/XrdCmsTrace.hh"
00023 #include "XrdOuc/XrdOucErrInfo.hh"
00024 #include "XrdNet/XrdNetBuffer.hh"
00025 
00026 using namespace XrdCms;
00027  
00028 /******************************************************************************/
00029 /*                               G l o b a l s                                */
00030 /******************************************************************************/
00031   
00032 int               XrdCmsClientMsg::nextid   =  0;
00033 int               XrdCmsClientMsg::numinQ   =  0;
00034 
00035 XrdCmsClientMsg  *XrdCmsClientMsg::msgTab   =  0;
00036 XrdCmsClientMsg  *XrdCmsClientMsg::nextfree =  0;
00037 
00038 XrdSysMutex       XrdCmsClientMsg::FreeMsgQ;
00039 
00040 /******************************************************************************/
00041 /*                                 A l l o c                                  */
00042 /******************************************************************************/
00043   
00044 // Returns the message object locked!
00045 
00046 XrdCmsClientMsg *XrdCmsClientMsg::Alloc(XrdOucErrInfo *erp)
00047 {
00048    XrdCmsClientMsg *mp;
00049    int       lclid;
00050 
00051 // Allocate a message object
00052 //
00053    FreeMsgQ.Lock();
00054    if (nextfree) {mp = nextfree; nextfree = mp->next;}
00055       else {FreeMsgQ.UnLock(); return (XrdCmsClientMsg *)0;}
00056    lclid = nextid = (nextid + MidIncr) & IncMask;
00057    numinQ++;
00058    FreeMsgQ.UnLock();
00059 
00060 // Initialize it
00061 //
00062    mp->Hold.Lock();
00063    mp->id      = (mp->id & MidMask) | lclid;
00064    mp->Resp    = erp;
00065    mp->next    = 0;
00066    mp->inwaitq = 1;
00067 
00068 // Return the message object
00069 //
00070    return mp;
00071 }
00072  
00073 /******************************************************************************/
00074 /*                                  I n i t                                   */
00075 /******************************************************************************/
00076   
00077 int XrdCmsClientMsg::Init()
00078 {
00079    int i;
00080    XrdCmsClientMsg *msgp;
00081 
00082 // Allocate the fixed number of msg blocks. These will never be freed!
00083 //
00084    if (!(msgp = new XrdCmsClientMsg[MaxMsgs]())) return 1;
00085    msgTab = &msgp[0];
00086    nextid = MaxMsgs;
00087 
00088 // Place all of the msg blocks on the free list
00089 //
00090   for (i = 0; i < MaxMsgs; i++)
00091      {msgp->next = nextfree; nextfree = msgp; msgp->id = i; msgp++;}
00092 
00093 // All done
00094 //
00095    return 0;
00096 }
00097 
00098 /******************************************************************************/
00099 /*                               R e c y c l e                                */
00100 /******************************************************************************/
00101   
00102 // Message object lock *must* be held by the caller upon entry!
00103 
00104 void XrdCmsClientMsg::Recycle()
00105 {
00106    static XrdOucErrInfo dummyResp;
00107 
00108 // Remove this from he wait queue and substitute a safe resp object. We do
00109 // this because a reply may be pending and will post when we release the lock
00110 //
00111    inwaitq = 0; 
00112    Resp = &dummyResp;
00113    Hold.UnLock();
00114 
00115 // Place message object on re-usable queue
00116 //
00117    FreeMsgQ.Lock();
00118    next = nextfree; 
00119    nextfree = this; 
00120    if (numinQ >= 0) numinQ--;
00121    FreeMsgQ.UnLock();
00122 }
00123 
00124 /******************************************************************************/
00125 /*                                 R e p l y                                  */
00126 /******************************************************************************/
00127   
00128 int XrdCmsClientMsg::Reply(const char *Man, CmsRRHdr &hdr, XrdNetBuffer *buff)
00129 {
00130    EPNAME("Reply")
00131    XrdCmsClientMsg *mp;
00132 
00133 // Find the appropriate message
00134 //
00135    if (!(mp = XrdCmsClientMsg::RemFromWaitQ(hdr.streamid)))
00136       {DEBUG("to non-existent message; id=" <<hdr.streamid);
00137        return 0;
00138       }
00139 
00140 // Decode the response
00141 //
00142    mp->Result = XrdCmsParser::Decode(Man, hdr, buff->data, buff->dlen,
00143                                      (XrdOucErrInfo *)(mp->Resp));
00144 
00145 // Signal a reply and return
00146 //
00147    mp->Hold.Signal();
00148    mp->Hold.UnLock();
00149    return 1;
00150 }
00151 
00152 /******************************************************************************/
00153 /*                       P r i v a t e   M e t h o d s                        */
00154 /******************************************************************************/
00155 /******************************************************************************/
00156 /*                          R e m F r o m W a i t Q                           */
00157 /******************************************************************************/
00158 
00159 // RemFromWaitQ() returns the msg object with the object locked! The caller
00160 //                must unlock the object.
00161   
00162 XrdCmsClientMsg *XrdCmsClientMsg::RemFromWaitQ(int msgid)
00163 {
00164    int msgnum;
00165 
00166 // Locate the message object (the low order bits index it)
00167 //
00168   msgnum = msgid & MidMask;
00169   msgTab[msgnum].Hold.Lock();
00170   if (!msgTab[msgnum].inwaitq || msgTab[msgnum].id != msgid)
00171      {msgTab[msgnum].Hold.UnLock(); return (XrdCmsClientMsg *)0;}
00172   msgTab[msgnum].inwaitq = 0;
00173   return &msgTab[msgnum];
00174 }

Generated on Tue Jul 5 14:46:23 2011 for ROOT_528-00b_version by  doxygen 1.5.1