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

  1 mike  1.2 //%///////////-*-c++-*-//////////////////////////////////////////////////////
  2           //
  3           // Copyright (c) 2000, 2001 The Open group, BMC Software, Tivoli Systems, IBM
  4           //
  5 mike  1.5 // Permission is hereby granted, free of charge, to any person obtaining a copy
  6 mike  1.2 // of this software and associated documentation files (the "Software"), to 
  7           // deal in the Software without restriction, including without limitation the 
  8           // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 
  9           // sell copies of the Software, and to permit persons to whom the Software is
 10           // furnished to do so, subject to the following conditions:
 11           // 
 12           // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN 
 13           // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 14           // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 15           // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
 16           // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
 17           // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
 18           // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 19           // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 20           //
 21           //==============================================================================
 22           //
 23           // Author: Mike Day (mdday@us.ibm.com)
 24           //
 25           // Modified By: 
 26           //
 27 mike  1.2 //%/////////////////////////////////////////////////////////////////////////////
 28           
 29           
 30           #ifndef Pegasus_AsyncOpNode_h
 31           #define Pegasus_AsyncOpNode_h
 32           
 33           #include <Pegasus/Common/Config.h>
 34           #include <Pegasus/Common/Message.h>
 35           #include <Pegasus/Common/OperationContext.h>
 36           #include <Pegasus/Common/internal_dq.h>
 37           #include <Pegasus/Common/IPC.h>
 38           
 39           PEGASUS_NAMESPACE_BEGIN
 40 mike  1.5 
 41 mday  1.15 // ATTN usage of flags and state is inconsistent
 42 mday  1.14 // << Wed Jan 16 17:41:57 2002 mdd >>
 43 mday  1.17 // resolved mdd 
 44            
 45 mike  1.2  
 46            #define ASYNC_OPFLAGS_UNKNOWN           0x00000000
 47            #define ASYNC_OPFLAGS_INTERVAL_REPEAT   0x00000010
 48            #define ASYNC_OPFLAGS_INDICATION        0x00000020
 49            #define ASYNC_OPFLAGS_REMOTE            0x00000040
 50            #define ASYNC_OPFLAGS_LOCAL_OUT_OF_PROC 0x00000080
 51            #define ASYNC_OPFLAGS_PHASED            0x00000001
 52            #define ASYNC_OPFLAGS_PARTIAL           0x00000002
 53            #define ASYNC_OPFLAGS_NORMAL            0x00000000
 54            #define ASYNC_OPFLAGS_SINGLE            0x00000008
 55            #define ASYNC_OPFLAGS_MULTIPLE          0x00000010
 56            #define ASYNC_OPFLAGS_TOTAL             0x00000020
 57 mday  1.13 #define ASYNC_OPFLAGS_META_DISPATCHER   0x00000040
 58 mday  1.17 #define ASYNC_OPFLAGS_FIRE_AND_FORGET   0x00000080
 59            #define ASYNC_OPFLAGS_SIMPLE_STATUS     0x00000100
 60            #define ASYNC_OPFLAGS_CALLBACK          0x00000200
 61 mday  1.20 #define ASYNC_OPFLAGS_FORWARD           0x00000400
 62 mike  1.2  
 63            #define ASYNC_OPSTATE_UNKNOWN           0x00000000
 64            #define ASYNC_OPSTATE_OFFERED           0x00000001
 65            #define ASYNC_OPSTATE_DECLINED          0x00000002
 66            #define ASYNC_OPSTATE_STARTED           0x00000004
 67            #define ASYNC_OPSTATE_PROCESSING        0x00000008
 68            #define ASYNC_OPSTATE_DELIVER           0x00000010 
 69            #define ASYNC_OPSTATE_RESERVE           0x00000020
 70            #define ASYNC_OPSTATE_COMPLETE          0x00000040
 71            #define ASYNC_OPSTATE_TIMEOUT           0x00000080
 72            #define ASYNC_OPSTATE_CANCELLED         0x00000100
 73            #define ASYNC_OPSTATE_PAUSED            0x00000200
 74 mday  1.12 #define ASYNC_OPSTATE_SUSPENDED         0x00000400
 75 mday  1.3  #define ASYNC_OPSTATE_RESUMED           0x00000800
 76 mday  1.8  #define ASYNC_OPSTATE_ORPHANED          0x00001000
 77 mday  1.12 #define ASYNC_OPSTATE_RELEASED          0x00002000
 78 mike  1.2  
 79 mday  1.8  class Cimom;
 80 mday  1.23 class Thread;
 81 mday  1.13 
 82 mike  1.2  class PEGASUS_COMMON_LINKAGE AsyncOpNode
 83            {
 84               public:
 85            
 86                  AsyncOpNode(void);
 87                  ~AsyncOpNode(void);
 88                        
 89                  Boolean  operator == (const void *key) const;
 90                  Boolean operator == (const AsyncOpNode & node) const;
 91 mday  1.9  
 92 mday  1.12       void get_timeout_interval(struct timeval *buffer) ;
 93 mday  1.9        void set_timeout_interval(const struct timeval *interval);
 94                  
 95 mike  1.2        Boolean timeout(void)  ;
 96            
 97                  OperationContext & get_context(void) ;
 98            
 99 mday  1.4        void put_request(const Message *request) ;
100 mday  1.13       Message *get_request(void) ;
101 mike  1.2        
102 mday  1.4        void put_response(const Message *response) ;
103 mday  1.13       Message *get_response(void) ;
104 mike  1.2        
105                  Uint32 read_state(void) ;
106                  void write_state(Uint32) ;
107 mday  1.11       
108 mike  1.2        Uint32 read_flags(void);
109                  void write_flags(Uint32);
110                  
111                  void lock(void)  throw(IPCException);
112                  void unlock(void) throw(IPCException);
113                  void udpate(void) throw(IPCException);
114                  void deliver(const Uint32 count) throw(IPCException);
115                  void reserve(const Uint32 size) throw(IPCException);
116                  void processing(void) throw(IPCException) ;
117                  void processing(OperationContext *context) throw(IPCException);
118                  void complete(void) throw(IPCException) ;
119                  void complete(OperationContext *context) throw(IPCException);
120 mday  1.12       void release(void);
121 mday  1.10       void wait(void);
122                  
123 mike  1.2        
124               private:
125                  Semaphore _client_sem;
126                  Mutex _mut;
127 mday  1.16       unlocked_dq<Message> _request;
128                  unlocked_dq<Message> _response; 
129 mday  1.15       
130 mike  1.2        OperationContext _operation_list;
131                  Uint32 _state;
132                  Uint32 _flags;
133                  Uint32 _offered_count;
134                  Uint32 _total_ops;
135                  Uint32 _completed_ops;
136 mday  1.15       Uint32 _user_data;
137 mday  1.17       Uint32 _completion_code;
138 mday  1.19       MessageQueue *_op_dest;
139 mday  1.17             
140 mike  1.2        struct timeval _start;
141                  struct timeval _lifetime;
142                  struct timeval _updated;
143                  struct timeval _timeout_interval;
144            
145                  AsyncOpNode *_parent;
146                  unlocked_dq<AsyncOpNode> _children;
147            
148                  void _reset(unlocked_dq<AsyncOpNode> *dst_q);
149            
150 mday  1.9        // the lifetime member is for cache management by the cimom
151 mike  1.2        void _set_lifetime(struct timeval *lifetime) ;
152 mday  1.12       Boolean _check_lifetime(void) ;
153 mike  1.2  
154                  Boolean _is_child(void) ;
155                  Uint32 _is_parent(void) ;
156                  Boolean _is_my_child(const AsyncOpNode & caller) const;
157                  void _make_orphan( AsyncOpNode & parent) ;
158                  void _adopt_child(AsyncOpNode *child) ;
159                  void _disown_child(AsyncOpNode *child) ;
160 mday  1.18       void (*_async_callback)(AsyncOpNode *, 
161 mday  1.19 			      MessageQueue *, 
162 mday  1.18 			      void *);
163 mday  1.23       // << Tue Mar 12 14:44:51 2002 mdd >>
164                  // pointers for async callbacks  - don't use 
165 mday  1.19       AsyncOpNode *_callback_node;
166 mday  1.21       MessageQueue *_callback_response_q;
167 mday  1.19       void *_callback_ptr;
168 mday  1.22       MessageQueue *_callback_request_q;
169 mday  1.23       //      << Tue Mar 12 14:44:53 2002 mdd >>
170                  // pointers to help static class message handlers - don't use 
171                  MessageQueue *_service_ptr;
172                  Thread *_thread_ptr;
173                        
174 mday  1.8        friend class cimom;
175 mday  1.10       friend class MessageQueueService;
176                  
177 mike  1.2  };
178            
179            
180            inline Boolean AsyncOpNode::operator == (const void *key) const
181            {
182               if (key == (void *)this)
183                  return true;
184               return false;
185            }
186            
187            inline Boolean AsyncOpNode::operator == (const AsyncOpNode & node) const
188            {
189               return AsyncOpNode::operator==((const void *)&node);
190            }
191            
192 mday  1.9  
193 mday  1.12 inline void AsyncOpNode::get_timeout_interval(struct timeval *buffer) 
194 mday  1.9  {
195               if(buffer != 0)
196               {
197 mday  1.12       _mut.lock( pegasus_thread_self() );
198 mday  1.9        buffer->tv_sec = _timeout_interval.tv_sec;
199                  buffer->tv_usec = _timeout_interval.tv_usec;
200 mday  1.12       _mut.unlock();
201 mday  1.9     }
202               return;
203            }
204            
205            inline void AsyncOpNode::set_timeout_interval(const struct timeval *interval)
206            {
207               if(interval != 0)
208               {
209 mday  1.12       _mut.lock(pegasus_thread_self());
210 mday  1.9        _timeout_interval.tv_sec = interval->tv_sec;
211                  _timeout_interval.tv_usec = interval->tv_usec;
212 mday  1.12       gettimeofday(&_updated, NULL);
213                  _mut.unlock();
214 mday  1.9     }
215            }
216            
217            
218 mike  1.2  inline Boolean AsyncOpNode::timeout(void) 
219            {
220               struct timeval now;
221               gettimeofday(&now, NULL);
222 mday  1.12    Boolean ret = false;
223               _mut.lock(pegasus_thread_self());
224 mday  1.15    if((_updated.tv_sec + _timeout_interval.tv_sec ) < now.tv_sec)
225                  if((_updated.tv_usec + _timeout_interval.tv_usec ) < now.tv_usec)
226 mday  1.12 	 ret =  true;
227               _mut.unlock();
228               return ret;
229 mike  1.2  }
230            
231 mday  1.4  // context is now a locked list
232 mday  1.3  inline OperationContext & AsyncOpNode::get_context(void)
233 mike  1.2  {
234 mday  1.9     gettimeofday(&_updated, NULL);
235 mike  1.2     return _operation_list;
236            }
237            
238 mday  1.16 
239 mday  1.4  inline  void AsyncOpNode::put_request(const Message *request) 
240 mike  1.2  {
241 mday  1.12    _mut.lock(pegasus_thread_self());
242 mday  1.9     gettimeofday(&_updated, NULL);
243 mday  1.21    if( false == _request.exists(reinterpret_cast<void *>(const_cast<Message *>(request))) )
244 mday  1.16    _request.insert_last( const_cast<Message *>(request) ) ;
245 mday  1.15 
246 mday  1.16 //   _request = const_cast<Message *>(request);
247 mday  1.15    
248 mday  1.12    _mut.unlock();
249 mike  1.2  }
250            
251 mday  1.13 inline Message * AsyncOpNode::get_request(void) 
252 mike  1.2  {
253 mday  1.12    Message *ret;
254               _mut.lock(pegasus_thread_self());
255 mday  1.9     gettimeofday(&_updated, NULL);
256 mday  1.16    ret = _request.remove_first() ;
257            //   ret = _request;
258 mday  1.15    
259 mday  1.12    _mut.unlock();
260               return ret;
261 mike  1.2  }
262            
263 mday  1.4  inline void AsyncOpNode::put_response(const Message *response) 
264 mike  1.2  {
265 mday  1.12    _mut.lock(pegasus_thread_self());
266 mday  1.9     gettimeofday(&_updated, NULL);
267 mday  1.21    if (false == _response.exists(reinterpret_cast<void *>(const_cast<Message *>(response))))
268 mday  1.16    _response.insert_last( const_cast<Message *>(response) );
269 mday  1.15 
270 mday  1.16 //   _response = const_cast<Message *>(response);
271 mday  1.15    
272 mday  1.12    _mut.unlock();
273 mike  1.2  }
274            
275 mday  1.13 inline Message * AsyncOpNode::get_response(void) 
276 mike  1.2  {
277 mday  1.12    Message *ret;
278            
279               _mut.lock(pegasus_thread_self());
280 mday  1.15 //   gettimeofday(&_updated, NULL);
281 mday  1.16    ret = _response.remove_first();
282            //   ret = _response;
283 mday  1.15    
284 mday  1.12    _mut.unlock();
285               return ret;
286 mike  1.2  }
287            
288            inline Uint32 AsyncOpNode::read_state(void)
289            {
290 mday  1.12    _mut.lock(pegasus_thread_self());
291 mday  1.9     gettimeofday(&_updated, NULL);
292 mday  1.12    Uint32 ret = _state;
293               _mut.unlock();
294               return ret;
295               
296 mike  1.2  }
297            
298            inline void AsyncOpNode::write_state(Uint32 state)
299            {
300 mday  1.12    _mut.lock(pegasus_thread_self());
301 mday  1.9     gettimeofday(&_updated, NULL);
302 mike  1.2     _state = state;
303 mday  1.12    _mut.unlock();
304 mike  1.2  }
305            
306            inline Uint32 AsyncOpNode::read_flags(void)
307            {
308 mday  1.12    _mut.lock(pegasus_thread_self());
309 mday  1.9     gettimeofday(&_updated, NULL);
310 mday  1.12    Uint32 ret = _flags;
311               _mut.unlock();
312               return ret;
313 mike  1.2  }
314            
315            inline void AsyncOpNode::write_flags(Uint32 flags)
316 mday  1.9  {   
317 mday  1.12    _mut.lock(pegasus_thread_self());
318 mday  1.9     gettimeofday(&_updated, NULL);
319 mike  1.2     _flags = flags;
320 mday  1.12    _mut.unlock();
321 mike  1.2  }
322            
323            
324            inline  void AsyncOpNode::lock(void)  
325               throw(IPCException) 
326            {
327               _mut.lock(pegasus_thread_self());
328            }
329            
330            inline void AsyncOpNode::unlock(void) 
331               throw(IPCException) 
332            {
333               _mut.unlock();
334            }
335            
336            inline void AsyncOpNode::udpate(void)
337               throw(IPCException)
338            {
339               _mut.lock(pegasus_thread_self());
340               gettimeofday(&_updated, NULL);
341               _mut.unlock();
342 mike  1.2     return;
343            }
344            
345            inline void AsyncOpNode::deliver(const Uint32 count) 
346               throw(IPCException)
347            {
348               _mut.lock(pegasus_thread_self());
349               _completed_ops = count;
350 mday  1.15    _state |= ASYNC_OPSTATE_DELIVER;
351 mike  1.2     gettimeofday(&_updated, NULL);
352               _mut.unlock();
353               return;
354            }
355            
356            inline void AsyncOpNode::reserve(const Uint32 size)
357               throw(IPCException)
358            {
359               _mut.lock(pegasus_thread_self());
360               _total_ops = size;
361 mday  1.15    _state |= ASYNC_OPSTATE_RESERVE;
362 mike  1.2     gettimeofday(&_updated, NULL);
363               _mut.unlock();
364               return;
365            }
366            
367            inline void AsyncOpNode::processing(void) 
368               throw(IPCException)
369            {
370               _mut.lock(pegasus_thread_self());
371 mday  1.15    _state |= ASYNC_OPSTATE_PROCESSING;
372 mike  1.2     gettimeofday(&_updated, NULL);
373               _mut.unlock();
374               return;
375            }
376            
377            // con will be empty upon return of this member function
378            inline void AsyncOpNode::processing(OperationContext *con) 
379               throw(IPCException)
380            {
381               _mut.lock(pegasus_thread_self());
382 mday  1.15    _state |= ASYNC_OPSTATE_PROCESSING;
383 mike  1.2     gettimeofday(&_updated, NULL);
384               
385               context *c = con->remove_context();
386               while(c != 0)
387               {
388                  _operation_list.add_context(c);
389                  c = con->remove_context();
390               }
391               _mut.unlock();
392               return;
393            }
394            
395            inline void AsyncOpNode::complete(void) 
396               throw(IPCException)
397            {
398               _mut.lock(pegasus_thread_self());
399 mday  1.15    _state |= ASYNC_OPSTATE_COMPLETE;
400 mike  1.2     gettimeofday(&_updated, NULL);
401               _mut.unlock();
402 mday  1.12 
403 mike  1.2     return;
404            }
405            
406            inline void AsyncOpNode::complete(OperationContext *con)
407               throw(IPCException)
408            {
409               _mut.lock(pegasus_thread_self());
410 mday  1.15    _state |= ASYNC_OPSTATE_COMPLETE;
411 mike  1.2     gettimeofday(&_updated, NULL);
412               context *c = con->remove_context();
413               while(c != 0)
414               {
415                  _operation_list.add_context(c);
416                  c = con->remove_context();
417               }
418               _mut.unlock();
419 mday  1.10 }
420            
421            inline void AsyncOpNode::wait(void)
422            {
423               _client_sem.wait();
424 mike  1.2  }
425            
426 mday  1.12 inline void AsyncOpNode::release(void)
427            {
428               _mut.lock(pegasus_thread_self());
429               _state |= ASYNC_OPSTATE_RELEASED;
430               _mut.unlock();
431            }
432            
433 mike  1.2  inline  void AsyncOpNode::_set_lifetime(struct timeval *lifetime) 
434            {
435 mday  1.12    _mut.lock(pegasus_thread_self());
436 mike  1.2     _lifetime.tv_sec = lifetime->tv_sec;
437               _lifetime.tv_usec = lifetime->tv_usec;
438 mday  1.12    _mut.unlock();
439 mike  1.2  }
440            
441 mday  1.12 inline Boolean AsyncOpNode::_check_lifetime(void) 
442 mike  1.2  {
443               struct timeval now;
444 mday  1.12    
445 mike  1.2     gettimeofday(&now, NULL);
446               if((_start.tv_sec + _lifetime.tv_sec ) >= now.tv_sec)
447                  if((_start.tv_usec + _lifetime.tv_usec ) >= now.tv_usec)
448            	 return true;
449               return false;
450            }
451            
452            inline Boolean AsyncOpNode::_is_child(void)
453            {
454               if (_parent != 0)
455                  return true;
456               return false;
457            }
458            
459            inline Uint32 AsyncOpNode::_is_parent(void)
460            {
461               return _children.count();
462            }
463            
464            inline Boolean AsyncOpNode::_is_my_child(const AsyncOpNode & caller) const
465            { 
466 mike  1.2     if ( _parent == &caller )
467                  return true;
468               return false;
469            }
470            
471            inline void AsyncOpNode::_make_orphan( AsyncOpNode & parent) 
472            {
473               if( _parent == &parent )
474               {
475                  _parent = NULL;
476                  parent._children.remove(this);
477               }
478               else
479                  throw Permission(pegasus_thread_self());
480            }
481            
482            inline void AsyncOpNode::_adopt_child(AsyncOpNode *child) 
483            {
484               if(child == NULL)
485                  throw NullPointer();
486               if(true == child->_is_child())
487 mike  1.2        throw Permission(pegasus_thread_self());
488               child->_parent = this;
489               _children.insert_last(child);
490            }
491                  
492            inline void AsyncOpNode::_disown_child(AsyncOpNode *child)
493            {
494               if(child == NULL)
495                  throw NullPointer();
496               if( false == child->_is_child() || false == child->_is_my_child( *this ))
497                  throw Permission(pegasus_thread_self());
498               child->_make_orphan( *this );
499               _children.remove(child);
500            } 
501            
502            PEGASUS_NAMESPACE_END
503            
504            #endif //Pegasus_AsyncOpNode_h

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2