XRootD
XrdCmsClientMsg.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d C m s C l i e n t M s g . c c */
4 /* */
5 /* (c) 2007 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* All Rights Reserved */
7 /* Produced by Andrew Hanushevsky for Stanford University under contract */
8 /* DE-AC02-76-SFO0515 with the Department of Energy */
9 /* */
10 /* This file is part of the XRootD software suite. */
11 /* */
12 /* XRootD is free software: you can redistribute it and/or modify it under */
13 /* the terms of the GNU Lesser General Public License as published by the */
14 /* Free Software Foundation, either version 3 of the License, or (at your */
15 /* option) any later version. */
16 /* */
17 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20 /* License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25 /* */
26 /* The copyright holder's institutional names and contributor's names may not */
27 /* be used to endorse or promote products derived from this software without */
28 /* specific prior written permission of the institution or contributor. */
29 /******************************************************************************/
30 
31 #include <cstdlib>
32 
33 #include "XProtocol/YProtocol.hh"
35 #include "XrdCms/XrdCmsParser.hh"
36 #include "XrdCms/XrdCmsTrace.hh"
37 #include "XrdOuc/XrdOucBuffer.hh"
38 #include "XrdOuc/XrdOucErrInfo.hh"
39 
40 using namespace XrdCms;
41 
42 /******************************************************************************/
43 /* G l o b a l s */
44 /******************************************************************************/
45 
46 int XrdCmsClientMsg::nextid = 0;
47 int XrdCmsClientMsg::numinQ = 0;
48 
49 XrdCmsClientMsg *XrdCmsClientMsg::msgTab = 0;
50 XrdCmsClientMsg *XrdCmsClientMsg::nextfree = 0;
51 
52 XrdSysMutex XrdCmsClientMsg::FreeMsgQ;
53 
54 /******************************************************************************/
55 /* A l l o c */
56 /******************************************************************************/
57 
58 // Returns the message object locked!
59 
61 {
62  XrdCmsClientMsg *mp;
63  int lclid;
64 
65 // Allocate a message object
66 //
67  FreeMsgQ.Lock();
68  if (nextfree) {mp = nextfree; nextfree = mp->next;}
69  else {FreeMsgQ.UnLock(); return (XrdCmsClientMsg *)0;}
70  lclid = nextid = (nextid + MidIncr) & IncMask;
71  numinQ++;
72  FreeMsgQ.UnLock();
73 
74 // Initialize it
75 //
76  mp->Hold.Lock();
77  mp->id = (mp->id & MidMask) | lclid;
78  mp->Resp = erp;
79  mp->next = 0;
80  mp->inwaitq = 1;
81 
82 // Return the message object
83 //
84  return mp;
85 }
86 
87 /******************************************************************************/
88 /* I n i t */
89 /******************************************************************************/
90 
92 {
93  int i;
94  XrdCmsClientMsg *msgp;
95 
96 // Allocate the fixed number of msg blocks. These will never be freed!
97 //
98  if (!(msgp = new XrdCmsClientMsg[MaxMsgs]())) return 1;
99  msgTab = &msgp[0];
100  nextid = MaxMsgs;
101 
102 // Place all of the msg blocks on the free list
103 //
104  for (i = 0; i < MaxMsgs; i++)
105  {msgp->next = nextfree; nextfree = msgp; msgp->id = i; msgp++;}
106 
107 // All done
108 //
109  return 0;
110 }
111 
112 /******************************************************************************/
113 /* R e c y c l e */
114 /******************************************************************************/
115 
116 // Message object lock *must* be held by the caller upon entry!
117 
119 {
120  static XrdOucErrInfo dummyResp;
121 
122 // Remove this from he wait queue and substitute a safe resp object. We do
123 // this because a reply may be pending and will post when we release the lock
124 //
125  inwaitq = 0;
126  Resp = &dummyResp;
127  Hold.UnLock();
128 
129 // Place message object on re-usable queue
130 //
131  FreeMsgQ.Lock();
132  next = nextfree;
133  nextfree = this;
134  if (numinQ >= 0) numinQ--;
135  FreeMsgQ.UnLock();
136 }
137 
138 /******************************************************************************/
139 /* R e p l y */
140 /******************************************************************************/
141 
142 int XrdCmsClientMsg::Reply(const char *Man, CmsRRHdr &hdr, XrdOucBuffer *buff)
143 {
144  EPNAME("Reply")
145  XrdCmsClientMsg *mp;
146 
147 // Find the appropriate message
148 //
149  if (!(mp = XrdCmsClientMsg::RemFromWaitQ(hdr.streamid)))
150  {DEBUG("to non-existent message; id=" <<hdr.streamid);
151  return 0;
152  }
153 
154 // Decode the response
155 //
156  mp->Result = XrdCmsParser::Decode(Man,hdr,buff,(XrdOucErrInfo *)(mp->Resp));
157 
158 // Signal a reply and return
159 //
160  mp->Hold.Signal();
161  mp->Hold.UnLock();
162  return 1;
163 }
164 
165 /******************************************************************************/
166 /* P r i v a t e M e t h o d s */
167 /******************************************************************************/
168 /******************************************************************************/
169 /* R e m F r o m W a i t Q */
170 /******************************************************************************/
171 
172 // RemFromWaitQ() returns the msg object with the object locked! The caller
173 // must unlock the object.
174 
175 XrdCmsClientMsg *XrdCmsClientMsg::RemFromWaitQ(int msgid)
176 {
177  int msgnum;
178 
179 // Locate the message object (the low order bits index it)
180 //
181  msgnum = msgid & MidMask;
182  msgTab[msgnum].Hold.Lock();
183  if (!msgTab[msgnum].inwaitq || msgTab[msgnum].id != msgid)
184  {msgTab[msgnum].Hold.UnLock(); return (XrdCmsClientMsg *)0;}
185  msgTab[msgnum].inwaitq = 0;
186  return &msgTab[msgnum];
187 }
#define DEBUG(x)
Definition: XrdBwmTrace.hh:54
#define EPNAME(x)
Definition: XrdBwmTrace.hh:56
static XrdCmsClientMsg * Alloc(XrdOucErrInfo *erp)
static int Init()
static int Reply(const char *Man, XrdCms::CmsRRHdr &hdr, XrdOucBuffer *buff)
static int Decode(const char *Man, XrdCms::CmsRRHdr &hdr, XrdOucBuffer *dBuff, XrdOucErrInfo *eInfo)
kXR_unt32 streamid
Definition: YProtocol.hh:83