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 kumpf 1.36 #ifdef PEGASUS_ASYNCOPNODE_MEMORY_OPTIMIZATION
85 // Note: These memory operators cause memory corruption errors because they
86 // are not compatible with the "::operator delete()" function used in
87 // internal_dq::empty_list()
|
88 mday 1.27 public:
|
89 mday 1.26 static void * operator new(size_t );
90 static void operator delete( void *, size_t);
91 private:
92 static AsyncOpNode * _headOfFreeList;
93 static const int BLOCK_SIZE;
94 static Mutex _alloc_mut;
|
95 kumpf 1.36 #endif
|
96 mike 1.2 public:
97
98 AsyncOpNode(void);
99 ~AsyncOpNode(void);
|
100 chip 1.30
|
101 mike 1.2 Boolean operator == (const void *key) const;
102 Boolean operator == (const AsyncOpNode & node) const;
|
103 mday 1.9
|
104 mday 1.12 void get_timeout_interval(struct timeval *buffer) ;
|
105 mday 1.9 void set_timeout_interval(const struct timeval *interval);
|
106 chip 1.30
|
107 mike 1.2 Boolean timeout(void) ;
108
109 OperationContext & get_context(void) ;
110
|
111 mday 1.4 void put_request(const Message *request) ;
|
112 mday 1.13 Message *get_request(void) ;
|
113 chip 1.30
|
114 mday 1.4 void put_response(const Message *response) ;
|
115 mday 1.13 Message *get_response(void) ;
|
116 chip 1.30
|
117 mike 1.2 Uint32 read_state(void) ;
118 void write_state(Uint32) ;
|
119 chip 1.30
|
120 mike 1.2 Uint32 read_flags(void);
121 void write_flags(Uint32);
|
122 chip 1.30
|
123 mike 1.2 void lock(void) throw(IPCException);
124 void unlock(void) throw(IPCException);
125 void udpate(void) throw(IPCException);
126 void deliver(const Uint32 count) throw(IPCException);
127 void reserve(const Uint32 size) throw(IPCException);
128 void processing(void) throw(IPCException) ;
129 void processing(OperationContext *context) throw(IPCException);
130 void complete(void) throw(IPCException) ;
131 void complete(OperationContext *context) throw(IPCException);
|
132 mday 1.12 void release(void);
|
133 mday 1.10 void wait(void);
|
134 chip 1.30
135
|
136 mike 1.2 private:
137 Semaphore _client_sem;
138 Mutex _mut;
|
139 mday 1.16 unlocked_dq<Message> _request;
|
140 chip 1.30 unlocked_dq<Message> _response;
141
|
142 mike 1.2 OperationContext _operation_list;
143 Uint32 _state;
144 Uint32 _flags;
145 Uint32 _offered_count;
146 Uint32 _total_ops;
147 Uint32 _completed_ops;
|
148 mday 1.15 Uint32 _user_data;
|
149 mday 1.17 Uint32 _completion_code;
|
150 mday 1.19 MessageQueue *_op_dest;
|
151 chip 1.30
|
152 mike 1.2 struct timeval _start;
153 struct timeval _lifetime;
154 struct timeval _updated;
155 struct timeval _timeout_interval;
156
157 AsyncOpNode *_parent;
158 unlocked_dq<AsyncOpNode> _children;
159
160 void _reset(unlocked_dq<AsyncOpNode> *dst_q);
161
|
162 mday 1.9 // the lifetime member is for cache management by the cimom
|
163 mike 1.2 void _set_lifetime(struct timeval *lifetime) ;
|
164 mday 1.12 Boolean _check_lifetime(void) ;
|
165 mike 1.2
166 Boolean _is_child(void) ;
167 Uint32 _is_parent(void) ;
168 Boolean _is_my_child(const AsyncOpNode & caller) const;
169 void _make_orphan( AsyncOpNode & parent) ;
170 void _adopt_child(AsyncOpNode *child) ;
171 void _disown_child(AsyncOpNode *child) ;
|
172 chip 1.30 void (*_async_callback)(AsyncOpNode *,
173 MessageQueue *,
|
174 mday 1.18 void *);
|
175 mday 1.26 void (*__async_callback)(Message *, void *, void *);
|
176 mday 1.23 // << Tue Mar 12 14:44:51 2002 mdd >>
|
177 chip 1.30 // pointers for async callbacks - don't use
|
178 mday 1.19 AsyncOpNode *_callback_node;
|
179 mday 1.21 MessageQueue *_callback_response_q;
|
180 mday 1.19 void *_callback_ptr;
|
181 mday 1.26 void *_callback_parameter;
182 void *_callback_handle;
|
183 mday 1.28 Condition *_callback_notify;
|
184 chip 1.30
|
185 mday 1.22 MessageQueue *_callback_request_q;
|
186 mday 1.23 // << Tue Mar 12 14:44:53 2002 mdd >>
|
187 chip 1.30 // pointers to help static class message handlers - don't use
|
188 mday 1.23 MessageQueue *_service_ptr;
189 Thread *_thread_ptr;
|
190 chip 1.30
|
191 mday 1.8 friend class cimom;
|
192 mday 1.10 friend class MessageQueueService;
|
193 mday 1.29 friend class ProviderManagerService;
|
194 mday 1.32 public:
195 // << Tue Jun 4 16:44:09 2002 mdd >>
196 // debug artifact
197 Uint32 _source_queue;
|
198 mday 1.34 // << Fri Jul 19 08:41:45 2002 mdd >>
199 // debugging utility
200 // careful - wipes out current value of *buf
201 void print_to_buffer(Sint8 **buf);
202 String &print_to_string(void);
|
203 mike 1.2 };
204
205
206 inline Boolean AsyncOpNode::operator == (const void *key) const
207 {
208 if (key == (void *)this)
209 return true;
210 return false;
211 }
212
213 inline Boolean AsyncOpNode::operator == (const AsyncOpNode & node) const
214 {
215 return AsyncOpNode::operator==((const void *)&node);
216 }
217
|
218 mday 1.9
|
219 chip 1.30 inline void AsyncOpNode::get_timeout_interval(struct timeval *buffer)
|
220 mday 1.9 {
221 if(buffer != 0)
222 {
|
223 mday 1.12 _mut.lock( pegasus_thread_self() );
|
224 mday 1.9 buffer->tv_sec = _timeout_interval.tv_sec;
225 buffer->tv_usec = _timeout_interval.tv_usec;
|
226 mday 1.12 _mut.unlock();
|
227 mday 1.9 }
228 return;
229 }
230
231 inline void AsyncOpNode::set_timeout_interval(const struct timeval *interval)
232 {
233 if(interval != 0)
234 {
|
235 mday 1.12 _mut.lock(pegasus_thread_self());
|
236 mday 1.9 _timeout_interval.tv_sec = interval->tv_sec;
237 _timeout_interval.tv_usec = interval->tv_usec;
|
238 mday 1.12 gettimeofday(&_updated, NULL);
239 _mut.unlock();
|
240 mday 1.9 }
241 }
242
243
|
244 chip 1.30 inline Boolean AsyncOpNode::timeout(void)
|
245 mike 1.2 {
246 struct timeval now;
247 gettimeofday(&now, NULL);
|
248 mday 1.12 Boolean ret = false;
249 _mut.lock(pegasus_thread_self());
|
250 mday 1.15 if((_updated.tv_sec + _timeout_interval.tv_sec ) < now.tv_sec)
251 if((_updated.tv_usec + _timeout_interval.tv_usec ) < now.tv_usec)
|
252 mday 1.12 ret = true;
253 _mut.unlock();
254 return ret;
|
255 mike 1.2 }
256
|
257 mday 1.4 // context is now a locked list
|
258 mday 1.3 inline OperationContext & AsyncOpNode::get_context(void)
|
259 mike 1.2 {
|
260 mday 1.9 gettimeofday(&_updated, NULL);
|
261 mike 1.2 return _operation_list;
262 }
263
|
264 mday 1.16
|
265 chip 1.30 inline void AsyncOpNode::put_request(const Message *request)
|
266 mike 1.2 {
|
267 mday 1.12 _mut.lock(pegasus_thread_self());
|
268 mday 1.9 gettimeofday(&_updated, NULL);
|
269 mday 1.21 if( false == _request.exists(reinterpret_cast<void *>(const_cast<Message *>(request))) )
|
270 mday 1.16 _request.insert_last( const_cast<Message *>(request) ) ;
|
271 mday 1.15
|
272 mday 1.16 // _request = const_cast<Message *>(request);
|
273 chip 1.30
|
274 mday 1.12 _mut.unlock();
|
275 mike 1.2 }
276
|
277 chip 1.30 inline Message * AsyncOpNode::get_request(void)
|
278 mike 1.2 {
|
279 mday 1.12 Message *ret;
280 _mut.lock(pegasus_thread_self());
|
281 mday 1.9 gettimeofday(&_updated, NULL);
|
282 mday 1.16 ret = _request.remove_first() ;
283 // ret = _request;
|
284 chip 1.30
|
285 mday 1.12 _mut.unlock();
286 return ret;
|
287 mike 1.2 }
288
|
289 chip 1.30 inline void AsyncOpNode::put_response(const Message *response)
|
290 mike 1.2 {
|
291 mday 1.12 _mut.lock(pegasus_thread_self());
|
292 mday 1.9 gettimeofday(&_updated, NULL);
|
293 mday 1.21 if (false == _response.exists(reinterpret_cast<void *>(const_cast<Message *>(response))))
|
294 mday 1.16 _response.insert_last( const_cast<Message *>(response) );
|
295 mday 1.15
|
296 mday 1.16 // _response = const_cast<Message *>(response);
|
297 chip 1.30
|
298 mday 1.12 _mut.unlock();
|
299 mike 1.2 }
300
|
301 chip 1.30 inline Message * AsyncOpNode::get_response(void)
|
302 mike 1.2 {
|
303 mday 1.12 Message *ret;
304
305 _mut.lock(pegasus_thread_self());
|
306 mday 1.15 // gettimeofday(&_updated, NULL);
|
307 mday 1.16 ret = _response.remove_first();
308 // ret = _response;
|
309 chip 1.30
|
310 mday 1.12 _mut.unlock();
311 return ret;
|
312 mike 1.2 }
313
314 inline Uint32 AsyncOpNode::read_state(void)
315 {
|
316 mday 1.12 _mut.lock(pegasus_thread_self());
|
317 mday 1.9 gettimeofday(&_updated, NULL);
|
318 mday 1.12 Uint32 ret = _state;
319 _mut.unlock();
320 return ret;
|
321 chip 1.30
|
322 mike 1.2 }
323
324 inline void AsyncOpNode::write_state(Uint32 state)
325 {
|
326 mday 1.12 _mut.lock(pegasus_thread_self());
|
327 mday 1.9 gettimeofday(&_updated, NULL);
|
328 mike 1.2 _state = state;
|
329 mday 1.12 _mut.unlock();
|
330 mike 1.2 }
331
332 inline Uint32 AsyncOpNode::read_flags(void)
333 {
|
334 mday 1.12 _mut.lock(pegasus_thread_self());
|
335 mday 1.9 gettimeofday(&_updated, NULL);
|
336 mday 1.12 Uint32 ret = _flags;
337 _mut.unlock();
338 return ret;
|
339 mike 1.2 }
340
341 inline void AsyncOpNode::write_flags(Uint32 flags)
|
342 chip 1.30 {
|
343 mday 1.12 _mut.lock(pegasus_thread_self());
|
344 mday 1.9 gettimeofday(&_updated, NULL);
|
345 mike 1.2 _flags = flags;
|
346 mday 1.12 _mut.unlock();
|
347 mike 1.2 }
348
349
|
350 chip 1.30 inline void AsyncOpNode::lock(void)
351 throw(IPCException)
|
352 mike 1.2 {
353 _mut.lock(pegasus_thread_self());
354 }
355
|
356 chip 1.30 inline void AsyncOpNode::unlock(void)
357 throw(IPCException)
|
358 mike 1.2 {
359 _mut.unlock();
360 }
361
362 inline void AsyncOpNode::udpate(void)
363 throw(IPCException)
364 {
365 _mut.lock(pegasus_thread_self());
366 gettimeofday(&_updated, NULL);
367 _mut.unlock();
368 return;
369 }
370
|
371 chip 1.30 inline void AsyncOpNode::deliver(const Uint32 count)
|
372 mike 1.2 throw(IPCException)
373 {
374 _mut.lock(pegasus_thread_self());
375 _completed_ops = count;
|
376 mday 1.15 _state |= ASYNC_OPSTATE_DELIVER;
|
377 mike 1.2 gettimeofday(&_updated, NULL);
378 _mut.unlock();
379 return;
380 }
381
382 inline void AsyncOpNode::reserve(const Uint32 size)
383 throw(IPCException)
384 {
385 _mut.lock(pegasus_thread_self());
386 _total_ops = size;
|
387 mday 1.15 _state |= ASYNC_OPSTATE_RESERVE;
|
388 mike 1.2 gettimeofday(&_updated, NULL);
389 _mut.unlock();
390 return;
391 }
392
|
393 chip 1.30 inline void AsyncOpNode::processing(void)
|
394 mike 1.2 throw(IPCException)
395 {
396 _mut.lock(pegasus_thread_self());
|
397 mday 1.15 _state |= ASYNC_OPSTATE_PROCESSING;
|
398 mike 1.2 gettimeofday(&_updated, NULL);
399 _mut.unlock();
400 return;
401 }
402
403 // con will be empty upon return of this member function
|
404 chip 1.30 inline void AsyncOpNode::processing(OperationContext *con)
|
405 mike 1.2 throw(IPCException)
406 {
407 _mut.lock(pegasus_thread_self());
|
408 mday 1.15 _state |= ASYNC_OPSTATE_PROCESSING;
|
409 mike 1.2 gettimeofday(&_updated, NULL);
|
410 chip 1.30
411 /*
|
412 mike 1.2 context *c = con->remove_context();
413 while(c != 0)
414 {
415 _operation_list.add_context(c);
416 c = con->remove_context();
417 }
|
418 chip 1.30 */
|
419 mike 1.2 _mut.unlock();
420 return;
421 }
422
|
423 chip 1.30 inline void AsyncOpNode::complete(void)
|
424 mike 1.2 throw(IPCException)
425 {
426 _mut.lock(pegasus_thread_self());
|
427 mday 1.15 _state |= ASYNC_OPSTATE_COMPLETE;
|
428 mike 1.2 gettimeofday(&_updated, NULL);
429 _mut.unlock();
|
430 mday 1.12
|
431 mike 1.2 return;
432 }
433
434 inline void AsyncOpNode::complete(OperationContext *con)
435 throw(IPCException)
436 {
437 _mut.lock(pegasus_thread_self());
|
438 mday 1.15 _state |= ASYNC_OPSTATE_COMPLETE;
|
439 mike 1.2 gettimeofday(&_updated, NULL);
|
440 chip 1.30 /*
|
441 mike 1.2 context *c = con->remove_context();
442 while(c != 0)
443 {
444 _operation_list.add_context(c);
445 c = con->remove_context();
446 }
|
447 chip 1.30 */
|
448 mike 1.2 _mut.unlock();
|
449 mday 1.10 }
450
451 inline void AsyncOpNode::wait(void)
452 {
453 _client_sem.wait();
|
454 mike 1.2 }
455
|
456 mday 1.12 inline void AsyncOpNode::release(void)
457 {
458 _mut.lock(pegasus_thread_self());
459 _state |= ASYNC_OPSTATE_RELEASED;
460 _mut.unlock();
461 }
462
|
463 chip 1.30 inline void AsyncOpNode::_set_lifetime(struct timeval *lifetime)
|
464 mike 1.2 {
|
465 mday 1.12 _mut.lock(pegasus_thread_self());
|
466 mike 1.2 _lifetime.tv_sec = lifetime->tv_sec;
467 _lifetime.tv_usec = lifetime->tv_usec;
|
468 mday 1.12 _mut.unlock();
|
469 mike 1.2 }
470
|
471 chip 1.30 inline Boolean AsyncOpNode::_check_lifetime(void)
|
472 mike 1.2 {
473 struct timeval now;
|
474 chip 1.30
|
475 mike 1.2 gettimeofday(&now, NULL);
476 if((_start.tv_sec + _lifetime.tv_sec ) >= now.tv_sec)
477 if((_start.tv_usec + _lifetime.tv_usec ) >= now.tv_usec)
478 return true;
479 return false;
480 }
481
482 inline Boolean AsyncOpNode::_is_child(void)
483 {
484 if (_parent != 0)
485 return true;
486 return false;
487 }
488
489 inline Uint32 AsyncOpNode::_is_parent(void)
490 {
491 return _children.count();
492 }
493
494 inline Boolean AsyncOpNode::_is_my_child(const AsyncOpNode & caller) const
|
495 chip 1.30 {
|
496 mike 1.2 if ( _parent == &caller )
497 return true;
498 return false;
499 }
500
|
501 chip 1.30 inline void AsyncOpNode::_make_orphan( AsyncOpNode & parent)
|
502 mike 1.2 {
503 if( _parent == &parent )
504 {
505 _parent = NULL;
506 parent._children.remove(this);
507 }
508 else
509 throw Permission(pegasus_thread_self());
510 }
511
|
512 chip 1.30 inline void AsyncOpNode::_adopt_child(AsyncOpNode *child)
|
513 mike 1.2 {
514 if(child == NULL)
515 throw NullPointer();
516 if(true == child->_is_child())
517 throw Permission(pegasus_thread_self());
518 child->_parent = this;
519 _children.insert_last(child);
520 }
|
521 chip 1.30
|
522 mike 1.2 inline void AsyncOpNode::_disown_child(AsyncOpNode *child)
523 {
524 if(child == NULL)
525 throw NullPointer();
526 if( false == child->_is_child() || false == child->_is_my_child( *this ))
527 throw Permission(pegasus_thread_self());
528 child->_make_orphan( *this );
529 _children.remove(child);
|
530 chip 1.30 }
|
531 mike 1.2
532 PEGASUS_NAMESPACE_END
533
534 #endif //Pegasus_AsyncOpNode_h
|