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