(file) Return to MessageQueue.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

  1 karl  1.40 //%2005////////////////////////////////////////////////////////////////////////
  2 mike  1.4  //
  3 karl  1.39 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4            // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5            // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6 karl  1.36 // IBM Corp.; EMC Corporation, The Open Group.
  7 karl  1.39 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8            // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9 karl  1.40 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10            // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 mike  1.4  //
 12            // Permission is hereby granted, free of charge, to any person obtaining a copy
 13 chip  1.8  // of this software and associated documentation files (the "Software"), to
 14            // deal in the Software without restriction, including without limitation the
 15            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 16 mike  1.4  // sell copies of the Software, and to permit persons to whom the Software is
 17            // furnished to do so, subject to the following conditions:
 18 david.dillard 1.43 //
 19 chip          1.8  // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 20 mike          1.4  // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 21                    // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 22 chip          1.8  // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 23                    // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 24                    // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 25 mike          1.4  // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 26                    // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 27                    //
 28                    //==============================================================================
 29                    //
 30                    // Author: Mike Brasher (mbrasher@bmc.com)
 31                    //
 32 a.arora       1.38 // Modified By: Amit K Arora, IBM (amita@in.ibm.com) for Bug#1090
 33 joyce.j       1.41 //              Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) for Bug#2076
 34 david.dillard 1.43 //              David Dillard, VERITAS Software Corp.
 35                    //                  (david.dillard@veritas.com)
 36 aruran.ms     1.46 //              Aruran, IBM (ashanmug@in.ibm.com) for Bug# 3475
 37 mike          1.4  //
 38                    //%/////////////////////////////////////////////////////////////////////////////
 39                    
 40 mike          1.5  #include <Pegasus/Common/HashTable.h>
 41 mike          1.7  #include <Pegasus/Common/IPC.h>
 42 kumpf         1.19 #include <Pegasus/Common/Tracer.h>
 43 aruran.ms     1.46 #include "Stack.h"
 44 mike          1.4  #include "MessageQueue.h"
 45 mday          1.24 #include "MessageQueueService.h"
 46 mike          1.4  PEGASUS_USING_STD;
 47                    
 48                    PEGASUS_NAMESPACE_BEGIN
 49                    
 50 mike          1.5  typedef HashTable<Uint32, MessageQueue*, EqualFunc<Uint32>, HashFunc<Uint32> >
 51                        QueueTable;
 52                    
 53 mday          1.33 static QueueTable _queueTable(256);
 54 mday          1.28 static Mutex q_table_mut ;
 55 mike          1.5  
 56 mday          1.35 void MessageQueue::remove_myself(Uint32 qid)
 57                    {
 58 david.dillard 1.43     AutoMutex autoMut(q_table_mut);
 59                        _queueTable.remove(qid);
 60 mday          1.35 }
 61                    
 62 aruran.ms     1.46 static Stack<Uint32> _qid_stack;
 63                    static Uint32 _qid_next = CIMOM_Q_ID + 1;
 64                    static Mutex _qid_mutex;
 65 mday          1.35 
 66 david.dillard 1.43 Uint32 MessageQueue::getNextQueueId()
 67 mike          1.5  {
 68 aruran.ms     1.46     // If _qid_stack is empty, return _qid_next (and then increment _qid_next).
 69                        // Else return the top of the stack.
 70 mike          1.16 
 71 aruran.ms     1.46     AutoMutex autoMutex(_qid_mutex);
 72 chip          1.8  
 73 aruran.ms     1.46     if (_qid_stack.isEmpty())
 74                            return _qid_next++;
 75 chip          1.8  
 76 aruran.ms     1.46     Uint32 queueId = _qid_stack.top();
 77                        _qid_stack.pop();
 78                        return queueId;
 79                    }
 80 chip          1.8  
 81 aruran.ms     1.46 void MessageQueue::putQueueId(Uint32 queueId)
 82                    {
 83                        // Put the queueId on the top of the stack.
 84 mike          1.7  
 85 aruran.ms     1.46     AutoMutex autoMutex(_qid_mutex);
 86                        // Ignore an attempt to return the well-known queue id (CIMOM_Q_ID).
 87                        // This id is reserved for the CIMOM queue.
 88 mday          1.12 
 89 aruran.ms     1.46     if (queueId == CIMOM_Q_ID)
 90                            return;
 91 mday          1.24 
 92 aruran.ms     1.46     _qid_stack.push(queueId);
 93                    }
 94 mday          1.24 
 95 mike          1.16 MessageQueue::MessageQueue(
 96 david.dillard 1.43     const char* name,
 97 mike          1.16     Boolean async,
 98                        Uint32 queueId)
 99 mday          1.24    : _queueId(queueId), _capabilities(0), _count(0), _front(0), _back(0), _async(async)
100 mike          1.5  {
101 mike          1.16     //
102                        // Copy the name:
103                        //
104                    
105 david.dillard 1.43     PEG_METHOD_ENTER(TRC_MESSAGEQUEUESERVICE,"MessageQueue::MessageQueue()");
106 kumpf         1.19 
107 mike          1.16     if (!name)
108 david.dillard 1.43         name = "";
109 mike          1.16 
110                        _name = new char[strlen(name) + 1];
111                        strcpy(_name, name);
112                    
113 kumpf         1.25     Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL3,
114 kumpf         1.42         "MessageQueue::MessageQueue  name = %s, queueId = %u", name, queueId);
115 kumpf         1.19 
116 mike          1.16     //
117                        // Insert into queue table:
118                        //
119 a.arora       1.38     AutoMutex autoMut(q_table_mut);
120 david.dillard 1.43     while (!_queueTable.insert(_queueId, this))
121                            ;
122 chip          1.8  
123 david.dillard 1.43     PEG_METHOD_EXIT();
124 mike          1.5  }
125                    
126                    MessageQueue::~MessageQueue()
127                    {
128                        // ATTN-A: thread safety!
129 kumpf         1.25     PEG_METHOD_ENTER(TRC_MESSAGEQUEUESERVICE,"MessageQueue::~MessageQueue()");
130                        Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL3,
131 kumpf         1.19         "MessageQueue::~MessageQueue queueId = %i, name = %s", _queueId, _name);
132                    
133 a.arora       1.38     {
134 david.dillard 1.43         AutoMutex autoMut(q_table_mut);
135                            _queueTable.remove(_queueId);
136 a.arora       1.38     } // mutex unlocks here
137 david.dillard 1.43 
138 mike          1.16     // Free the name:
139 david.dillard 1.43 
140 mike          1.16     delete [] _name;
141 kumpf         1.19 
142 david.dillard 1.43     while(_front)
143 joyce.j       1.41     {
144                           Message* tmp = _front;
145                           _front = _front->_next;
146                           delete tmp;
147                        }
148 aruran.ms     1.46     
149                        // Return the queue id.
150                    
151                        putQueueId(_queueId);
152 joyce.j       1.41 
153 kumpf         1.25     PEG_METHOD_EXIT();
154 chip          1.8  }
155                    
156 kumpf         1.37 void MessageQueue::enqueue(Message* message)
157 mike          1.4  {
158 kumpf         1.25     PEG_METHOD_ENTER(TRC_MESSAGEQUEUESERVICE,"MessageQueue::enqueue()");
159 kumpf         1.19 
160 david.dillard 1.43     if (!message)
161 kumpf         1.19     {
162 david.dillard 1.43         Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL3,
163                                        "MessageQueue::enqueue failure");
164                            PEG_METHOD_EXIT();
165                            throw NullPointer();
166 kumpf         1.19     }
167 mike          1.7  
168 david.dillard 1.43     PEG_TRACE_STRING( TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL3,
169 kumpf         1.31                       String("Queue name: ") + getQueueName() ) ;
170 david.dillard 1.43     Tracer::trace   ( TRC_MESSAGEQUEUESERVICE,
171 kumpf         1.31                       Tracer::LEVEL3,
172 david.dillard 1.43                       "Message: [%s, %d]",
173                                          MessageTypeToString(message->getType()),
174 kumpf         1.31                       message->getKey() );
175 david.dillard 1.43 
176 a.arora       1.38     {
177                        AutoMutex autoMut(_mut);
178 mike          1.4      if (_back)
179                        {
180 david.dillard 1.43         _back->_next = message;
181                            message->_prev = _back;
182                            message->_next = 0;
183                            _back = message;
184 mike          1.4      }
185                        else
186                        {
187 david.dillard 1.43         _front = message;
188                            _back = message;
189                            message->_prev = 0;
190                            message->_next = 0;
191 mike          1.4      }
192                        message->_owner = this;
193 david.dillard 1.43 
194 mike          1.4      _count++;
195 kumpf         1.25     Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL4,
196 david.dillard 1.43                   "MessageQueue::enqueue _queueId = %d, _count = %d", _queueId, _count);
197                    
198 a.arora       1.38     } // mutex unlocks here
199 david.dillard 1.43 
200 mday          1.22     handleEnqueue();
201 kumpf         1.25     PEG_METHOD_EXIT();
202 mday          1.15 }
203                    
204 david.dillard 1.43 Message* MessageQueue::dequeue()
205 mike          1.4  {
206 kumpf         1.25     PEG_METHOD_ENTER(TRC_MESSAGEQUEUESERVICE,"MessageQueue::dequeue()");
207                    
208 a.arora       1.38     AutoMutex autoMut(_mut);
209 mike          1.4      if (_front)
210                        {
211 david.dillard 1.43         Message* message = _front;
212                            _front = _front->_next;
213                            if (_front)
214                                _front->_prev = 0;
215 mike          1.4  
216 david.dillard 1.43         if (_back == message)
217                                _back = 0;
218 kumpf         1.25 
219 david.dillard 1.43         _count--;
220 kumpf         1.25         Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL4,
221 david.dillard 1.43             "MessageQueue::dequeue _queueId = %d, _count = %d",
222 kumpf         1.26             _queueId, _count);
223 kumpf         1.25 
224 david.dillard 1.43         message->_next = 0;
225                            message->_prev = 0;
226                            message->_owner = 0;
227 kumpf         1.25 
228                            PEG_METHOD_EXIT();
229 david.dillard 1.43         return message;
230 mike          1.4      }
231 kumpf         1.25 
232                        PEG_METHOD_EXIT();
233 mike          1.4      return 0;
234                    }
235 mday          1.23 
236 mike          1.4  
237 david.dillard 1.43 
238                    void MessageQueue::remove(Message* message)
239 mike          1.4  {
240 kumpf         1.25     PEG_METHOD_ENTER(TRC_MESSAGEQUEUESERVICE,"MessageQueue::remove()");
241                    
242 mike          1.4      if (!message)
243 kumpf         1.25     {
244                            PEG_METHOD_EXIT();
245 david.dillard 1.43         throw NullPointer();
246 kumpf         1.25     }
247 mike          1.4  
248                        if (message->_owner != this)
249 kumpf         1.25     {
250                            PEG_METHOD_EXIT();
251 david.dillard 1.43         throw NoSuchMessageOnQueue();
252 kumpf         1.25     }
253 mike          1.4  
254 a.arora       1.38     {
255                        AutoMutex autoMut(_mut);
256 chip          1.8  
257 mike          1.4      if (message->_next)
258 david.dillard 1.43         message->_next->_prev = message->_prev;
259 mike          1.4      else
260 david.dillard 1.43         _back = message->_prev;
261 mike          1.4  
262                        if (message->_prev)
263 david.dillard 1.43         message->_prev->_next = message->_next;
264 mike          1.4      else
265 david.dillard 1.43         _front = message->_next;
266 mike          1.4  
267 mike          1.7      _count--;
268 kumpf         1.25     Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL4,
269                           "MessageQueue::remove _count = %d", _count);
270                    
271 a.arora       1.38     } // mutex unlocks here
272 chip          1.8  
273 mike          1.4      message->_prev = 0;
274                        message->_next = 0;
275                        message->_owner = 0;
276 kumpf         1.25 
277                        PEG_METHOD_EXIT();
278 mike          1.4  }
279                    
280 david.dillard 1.43 Message* MessageQueue::findByType(Uint32 type)
281 mike          1.4  {
282 david.dillard 1.43     AutoMutex autoMut(_mut);
283 chip          1.8  
284 mike          1.4      for (Message* m = front(); m; m = m->getNext())
285                        {
286 david.dillard 1.43         if (m->getType() == type)
287                            {
288                                return m;
289                            }
290 mike          1.4      }
291 david.dillard 1.43 
292 mike          1.4      return 0;
293                    }
294                    
295 david.dillard 1.43 Message* MessageQueue::findByKey(Uint32 key)
296 mike          1.4  {
297 david.dillard 1.43     AutoMutex autoMut(_mut);
298 chip          1.8  
299 mike          1.4      for (Message* m = front(); m; m = m->getNext())
300                        {
301 mike          1.7         if (m->getKey() == key)
302                           {
303 a.arora       1.38           return m;
304 mike          1.7         }
305 chip          1.8  
306 mike          1.4      }
307 david.dillard 1.43 
308 mike          1.4      return 0;
309                    }
310                    
311 joyce.j       1.44 #ifdef PEGASUS_DEBUG
312 david.dillard 1.43 void MessageQueue::print(ostream& os) const
313 mike          1.4  {
314 david.dillard 1.43     AutoMutex autoMut(const_cast<MessageQueue *>(this)->_mut);
315 chip          1.8  
316 david.dillard 1.43     for (const Message* m = front(); m; m = m->getNext())
317                            m->print(os);
318 mike          1.4  }
319 joyce.j       1.44 #endif
320 mike          1.4  
321 david.dillard 1.43 Message* MessageQueue::find(Uint32 type, Uint32 key)
322 mike          1.4  {
323 david.dillard 1.43     AutoMutex autoMut(_mut);
324 chip          1.8  
325 mike          1.4      for (Message* m = front(); m; m = m->getNext())
326                        {
327 david.dillard 1.43         if (m->getType() == type && m->getKey() == key)
328                            {
329                                return m;
330                            }
331 mike          1.4      }
332                    
333 mike          1.5      return 0;
334                    }
335                    
336 mike          1.7  const char* MessageQueue::getQueueName() const
337 mike          1.5  {
338 david.dillard 1.43     return _name;
339 mike          1.5  }
340                    
341 david.dillard 1.43 MessageQueue* MessageQueue::lookup(Uint32 queueId)
342 mike          1.5  {
343 kumpf         1.19 
344 mike          1.5      MessageQueue* queue = 0;
345 a.arora       1.38     AutoMutex autoMut(q_table_mut);
346 chip          1.8  
347 mike          1.5      if (_queueTable.lookup(queueId, queue))
348 mike          1.7      {
349 david.dillard 1.43         return queue;
350 mike          1.7      }
351 chip          1.8  
352 mike          1.7      // Not found!
353 mike          1.5  
354 kumpf         1.25     Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL3,
355 kumpf         1.42         "MessageQueue::lookup failure queueId = %u", queueId);
356 kumpf         1.19 
357 mike          1.4      return 0;
358 mike          1.6  }
359 mike          1.7  
360                    
361 david.dillard 1.43 MessageQueue* MessageQueue::lookup(const char *name)
362 mike          1.7  {
363 kumpf         1.19 
364 david.dillard 1.43     if(name == NULL)
365                            throw NullPointer();
366 chip          1.8  
367 david.dillard 1.43     AutoMutex autoMut(q_table_mut);
368 mike          1.7     for(QueueTable::Iterator i = _queueTable.start(); i; i++)
369                       {
370                            // ATTN: Need to decide how many characters to compare in queue names
371 david.dillard 1.43         if(! strcmp( ((MessageQueue *)i.value())->getQueueName(), name) )
372                            {
373                                return( (MessageQueue *)i.value());
374                            }
375                        }
376 chip          1.8  
377 david.dillard 1.43     Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL3,
378                                        "MessageQueue::lookup failure - name = %s", name);
379 kumpf         1.19 
380 david.dillard 1.43     return 0;
381 mike          1.7  }
382                    
383 mike          1.6  
384                    void MessageQueue::handleEnqueue()
385                    {
386                    
387 mike          1.4  }
388                    
389                    PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2