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