1 karl 1.48 //%2005////////////////////////////////////////////////////////////////////////
|
2 kumpf 1.34 //
|
3 karl 1.45 // 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.41 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.45 // 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.48 // 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 // Permission is hereby granted, free of charge, to any person obtaining a copy
13 // 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 // 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.49 //
|
19 mike 1.2 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
20 // 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 // 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 // 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.42 // Modified By: Amit K Arora, IBM (amita@in.ibm.com) for PEP#101
|
33 a.arora 1.44 // Alagaraja Ramasubramanian (alags_raj@in.ibm.com) for Bug#1090
|
34 a.arora 1.46 // Amit K Arora, IBM (amita@in.ibm.com) for Bug#2322
|
35 david.dillard 1.49 // David Dillard, VERITAS Software Corp.
36 // (david.dillard@veritas.com)
|
37 a.arora 1.50 // Amit K Arora, IBM (amita@in.ibm.com) for Bug#2960
|
38 mike 1.2 //
39 //%/////////////////////////////////////////////////////////////////////////////
40
41 #ifndef Pegasus_DQueue_h
42 #define Pegasus_DQueue_h
43
44 #include <Pegasus/Common/IPC.h>
|
45 kumpf 1.36 #include <Pegasus/Common/Linkage.h>
|
46 a.arora 1.42 #include <Pegasus/Common/AutoPtr.h>
|
47 mike 1.2
48 PEGASUS_NAMESPACE_BEGIN
49
|
50 tony 1.38 template<class L> class DQueue : public internal_dq
|
51 mike 1.2 {
|
52 david.dillard 1.49 public:
53 static void *operator new(size_t size);
54 static void operator delete(void *dead, size_t size);
55
56 private:
57 AutoPtr<Mutex> _mutex; //PEP101
58 AutoPtr<AtomicInt> _actual_count;
59 DQueue *_dq_next;
60 static DQueue<L> *_headOfFreeList;
61 static const int BLOCK_SIZE;
62 static Mutex _alloc_mut;
63
64 public:
65 typedef internal_dq Base;
|
66 david.dillard 1.51 DQueue();
|
67 david.dillard 1.49 DQueue(Boolean head);
68
69 virtual ~DQueue();
70
|
71 david.dillard 1.51 /**
72 @exception IPCException Indicates an IPC error occurred.
73 */
74 void lock();
75
76 /**
77 @exception IPCException Indicates an IPC error occurred.
78 */
79 void unlock();
80
81 /**
82 @exception IPCException Indicates an IPC error occurred.
83 */
84 void try_lock();
85
86 /**
87 @exception IPCException Indicates an IPC error occurred.
88 */
89 void insert_first_no_lock(L *element);
90
91 /**
92 david.dillard 1.51 @exception IPCException Indicates an IPC error occurred.
93 */
94 void insert_first(L *element);
95
96 /**
97 @exception IPCException Indicates an IPC error occurred.
98 */
99 void insert_last_no_lock(L *element);
100
101 /**
102 @exception IPCException Indicates an IPC error occurred.
103 */
104 void insert_last(L *element);
105
106 /**
107 @exception IPCException Indicates an IPC error occurred.
108 */
109 void empty_list();
110
111 /**
112 @exception IPCException Indicates an IPC error occurred.
113 david.dillard 1.51 */
114 L *remove_first();
115
116 /**
117 @exception IPCException Indicates an IPC error occurred.
118 */
119 L *remove_last();
120
121 /**
122 @exception IPCException Indicates an IPC error occurred.
123 */
124 L *remove_no_lock(const void *key);
125
126 /**
127 @exception IPCException Indicates an IPC error occurred.
128 */
129 L *remove_no_lock(const L *key);
130
131 /**
132 @exception IPCException Indicates an IPC error occurred.
133 */
134 david.dillard 1.51 L *remove(const void *key);
135
136 /**
137 @exception IPCException Indicates an IPC error occurred.
138 */
139 L *remove(const L *key);
140
141 /**
142 @exception IPCException Indicates an IPC error occurred.
143 */
144 L *reference(const void *key);
145
|
146 david.dillard 1.49 L *reference(const L *key);
|
147 david.dillard 1.51
148 /**
149 @exception IPCException Indicates an IPC error occurred.
150 */
151 L *next(const void * ref);
152
153 /**
154 @exception IPCException Indicates an IPC error occurred.
155 */
156 L *prev(const void *ref);
157
158 /**
159 @exception IPCException Indicates an IPC error occurred.
160 */
161 Boolean exists(const void *key);
162
163 /**
164 @exception IPCException Indicates an IPC error occurred.
165 */
166 Boolean exists(const L *key);
|
167 david.dillard 1.49
168 Uint32 count(void) { return _actual_count->value() ; }
169 Uint32 size(void) { return _actual_count->value() ; }
|
170 mike 1.2 } ;
171
|
172 david.dillard 1.49
|
173 mday 1.20
|
174 tony 1.38 template<class L> class AsyncDQueue: public internal_dq
|
175 mike 1.2 {
|
176 mday 1.20
|
177 david.dillard 1.49 public:
178 static void * operator new(size_t size);
179 static void operator delete(void *, size_t);
180
181 private: // asyncdqueue
182 AutoPtr<Mutex> _cond;
183 AutoPtr<Condition> _slot;
184 AutoPtr<Condition> _node;
185 AutoPtr<AtomicInt> _actual_count;
186 AutoPtr<AtomicInt> _disallow;
187 AutoPtr<AtomicInt> _capacity;
188 AsyncDQueue *_dq_next;
189
190 static AsyncDQueue *_headOfFreeList;
191 static const int BLOCK_SIZE;
|
192 david.dillard 1.51 static Mutex _alloc_mut;
|
193 david.dillard 1.49
|
194 david.dillard 1.51 /**
195 @exception IPCException Indicates an IPC error occurred.
196 */
197 void _insert_prep();
198
199 /**
200 @exception IPCException Indicates an IPC error occurred.
201 */
202 void _insert_recover();
203
204 /**
205 @exception IPCException Indicates an IPC error occurred.
206 */
207 void _unlink_prep();
208
209 /**
210 @exception IPCException Indicates an IPC error occurred.
211 */
212 void _unlink_recover();
213
214 /**
215 david.dillard 1.51 @exception IPCException Indicates an IPC error occurred.
216 */
217 L *_remove_no_lock(const void *key);
218
219 /**
220 @exception IPCException Indicates an IPC error occurred.
221 */
222 L *_remove_no_lock(const L *key);
|
223 david.dillard 1.49
224 public:
225 typedef internal_dq Base;
226
|
227 david.dillard 1.51 AsyncDQueue() ;
228 AsyncDQueue(Boolean head, Uint32 capacity);
229 virtual ~AsyncDQueue();
230 void shutdown_queue();
231 Boolean is_full();
232 Boolean is_empty();
233 Boolean is_shutdown();
234
235 /**
236 @exception IPCException Indicates an IPC error occurred.
237 */
238 void try_lock(PEGASUS_THREAD_TYPE myself);
239
240 /**
241 @exception IPCException Indicates an IPC error occurred.
242 */
243 void lock(PEGASUS_THREAD_TYPE myself);
244
|
245 david.dillard 1.49 void unlock(void);
|
246 david.dillard 1.51
247 /**
248 @exception IPCException Indicates an IPC error occurred.
249 */
250 void signal_slot(void);
251
252 /**
253 @exception IPCException Indicates an IPC error occurred.
254 */
255 void signal_node();
256
257 Condition *get_node_cond();
258 Condition *get_slot_cond();
259
260 /**
261 @exception IPCException Indicates an IPC error occurred.
262 */
263 void wait_for_node();
264
265 /**
266 @exception IPCException Indicates an IPC error occurred.
267 david.dillard 1.51 */
268 void set_capacity(Uint32 capacity);
269
270 Uint32 get_capacity();
271
272 /**
273 @exception IPCException Indicates an IPC error occurred.
274 */
275 void insert_first(L *element);
276
277 /**
278 @exception IPCException Indicates an IPC error occurred.
279 */
280 void insert_first_wait(L *element);
281
282 /**
283 @exception IPCException Indicates an IPC error occurred.
284 */
285 void insert_last(L *element);
286
287 /**
288 david.dillard 1.51 @exception IPCException Indicates an IPC error occurred.
289 */
290 void insert_last_wait(L *element);
291
292 /**
293 @exception IPCException Indicates an IPC error occurred.
294 */
295 void empty_list();
296
297 /**
298 @exception IPCException Indicates an IPC error occurred.
299 */
300 L *remove_first();
301
302 /**
303 @exception IPCException Indicates an IPC error occurred.
304 */
305 L *remove_first_wait();
306
307 /**
308 @exception IPCException Indicates an IPC error occurred.
309 david.dillard 1.51 */
310 L *remove_last();
311
312 /**
313 @exception IPCException Indicates an IPC error occurred.
314 */
315 L *remove_last_wait();
316
317 /**
318 @exception IPCException Indicates an IPC error occurred.
319 */
320 L *remove(const void *key);
321
322 /**
323 @exception IPCException Indicates an IPC error occurred.
324 */
325 L *remove(const L *key);
326
327 /**
328 @exception IPCException Indicates an IPC error occurred.
329 */
330 david.dillard 1.51 L *remove_no_lock(const void *key);
331
332 /**
333 @exception IPCException Indicates an IPC error occurred.
334 */
335 L *remove_no_lock(const L *key);
336
337 /**
338 @exception IPCException Indicates an IPC error occurred.
339 */
340 L *remove_wait(const void *key);
341
342 /**
343 @exception IPCException Indicates an IPC error occurred.
344 */
345 L *next(const L *ref);
346
347 /**
348 @exception IPCException Indicates an IPC error occurred.
349 */
350 L *prev(const L *ref);
351 david.dillard 1.51
352 /**
353 @exception IPCException Indicates an IPC error occurred.
354 */
355 L *reference(const void *key);
356
357 /**
358 @exception IPCException Indicates an IPC error occurred.
359 */
360 L *reference(const L *key);
361 Uint32 count();
362 Uint32 size();
|
363 mike 1.2 };
|
364 david.dillard 1.49
|
365 keith.petley 1.39 template<class L> DQueue<L> * DQueue<L>::_headOfFreeList = 0;
|
366 mday 1.29 template<class L> const int DQueue<L>::BLOCK_SIZE = 200;
|
367 mday 1.25 template<class L> Mutex DQueue<L>::_alloc_mut;
368
|
369 mday 1.29 template<class L> void *DQueue<L>::operator new(size_t size)
370 {
|
371 david.dillard 1.49 if (size != sizeof(DQueue<L>))
372 return ::operator new(size);
373
374 AutoMutex autoMut(_alloc_mut);
375
376 DQueue<L> *p = _headOfFreeList;
377 if(p)
378 _headOfFreeList = p->_dq_next;
379 else
380 {
381 DQueue<L> * newBlock =
382 static_cast<DQueue<L> *>(::operator new(BLOCK_SIZE * sizeof(DQueue<L>)));
383 int i;
384 for( i = 1; i < BLOCK_SIZE - 1; ++i)
385 newBlock[i]._dq_next = &newBlock[i + 1];
386 newBlock[BLOCK_SIZE - 1]._dq_next = 0;
387
388 p = newBlock;
389 _headOfFreeList = &newBlock[1];
390 }
|
391 a.arora 1.44
|
392 david.dillard 1.49
393 return p;
|
394 mday 1.29 }
395
396 template<class L> void DQueue<L>::operator delete(void *dead, size_t size)
397 {
|
398 david.dillard 1.49 if(dead == 0)
399 return;
400 if(size != sizeof(DQueue<L>))
401 {
402 ::operator delete(dead);
403 return;
404 }
405 DQueue<L> *p = static_cast<DQueue<L> *>(dead);
406 AutoMutex autoMut(_alloc_mut);
407 p->_dq_next = _headOfFreeList;
408 _headOfFreeList = p;
|
409 mday 1.29 }
|
410 mday 1.25
|
411 keith.petley 1.39 template<class L> AsyncDQueue<L> * AsyncDQueue<L>::_headOfFreeList =0;
|
412 mday 1.25 template<class L> const int AsyncDQueue<L>::BLOCK_SIZE = 20;
413 template<class L> Mutex AsyncDQueue<L>::_alloc_mut;
414
|
415 mday 1.29 template<class L> void * AsyncDQueue<L>::operator new(size_t size)
416 {
|
417 david.dillard 1.49 if (size != sizeof(AsyncDQueue<L>))
418 return ::operator new(size);
419
420 AutoMutex autoMut(_alloc_mut);
|
421 a.arora 1.44
|
422 david.dillard 1.49 AsyncDQueue<L> *p = _headOfFreeList;
423 if(p)
424 _headOfFreeList = p->_dq_next;
425 else
426 {
427 AsyncDQueue<L> * newBlock =
428 static_cast<AsyncDQueue<L> *>(::operator new(BLOCK_SIZE * sizeof(AsyncDQueue<L>)));
429 int i;
430 for( i = 1; i < BLOCK_SIZE - 1; ++i)
431 newBlock[i]._dq_next = &newBlock[i + 1];
432 newBlock[BLOCK_SIZE - 1]._dq_next = 0;
433
434 p = newBlock;
435 _headOfFreeList = &newBlock[1];
436 }
437
438 return p;
|
439 mday 1.29 }
440
441 template<class L> void AsyncDQueue<L>::operator delete(void *deadObject, size_t size)
442 {
|
443 david.dillard 1.49 if(deadObject == 0)
444 return;
445 if(size != sizeof(AsyncDQueue<L>))
446 {
447 ::operator delete(deadObject);
448 return;
449 }
450 AsyncDQueue<L> *p = static_cast<AsyncDQueue<L> *>(deadObject);
451 AutoMutex autoMut(_alloc_mut);
452 p->_dq_next = _headOfFreeList;
453 _headOfFreeList = p;
454 }
|
455 a.arora 1.44
|
456 david.dillard 1.51 template<class L> DQueue<L>::DQueue()
|
457 david.dillard 1.49 : Base(false)
458 {
|
459 mday 1.24
460 }
461
|
462 david.dillard 1.49 template<class L> DQueue<L>::DQueue(Boolean head)
463 : Base(head)
|
464 mday 1.24 {
|
465 david.dillard 1.49 if(head == true)
466 {
467 _mutex.reset(new Mutex());
468 _actual_count.reset(new AtomicInt(0));
469 }
|
470 mday 1.24 }
471
472
|
473 david.dillard 1.49 template<class L> DQueue<L>::~DQueue()
474 {
475
|
476 mday 1.24 }
477
478
|
479 david.dillard 1.51 template<class L> void DQueue<L>::lock()
|
480 david.dillard 1.49 {
481 _mutex->lock(pegasus_thread_self());
482 }
|
483 mday 1.24
|
484 david.dillard 1.51 template<class L> void DQueue<L>::unlock()
|
485 david.dillard 1.49 {
486 _mutex->unlock();
487 }
|
488 mday 1.24
|
489 david.dillard 1.51 template<class L> void DQueue<L>::try_lock()
|
490 david.dillard 1.49 {
491 _mutex->try_lock(pegasus_thread_self());
492 }
|
493 mday 1.24
|
494 david.dillard 1.51 template<class L> void DQueue<L>::insert_first_no_lock(L *element)
|
495 mday 1.24 {
|
496 david.dillard 1.49 if( pegasus_thread_self() != _mutex->get_owner())
497 throw Permission(pegasus_thread_self());
498 Base::insert_first(static_cast<void *>(element));
499 (*_actual_count.get())++;
|
500 mday 1.24 }
501
|
502 david.dillard 1.51 template<class L> void DQueue<L>::insert_first(L *element)
|
503 david.dillard 1.49 {
504 if(element == 0)
505 return;
506 AutoMutex autoMut(*_mutex.get());
507 Base::insert_first(static_cast<void *>(element));
508 (*_actual_count.get())++;
|
509 mday 1.24 }
510
|
511 david.dillard 1.51 template<class L> void DQueue<L>::insert_last_no_lock(L *element)
|
512 mday 1.24 {
|
513 david.dillard 1.49 if( pegasus_thread_self() != _mutex->get_owner())
514 throw Permission(pegasus_thread_self());
515 Base::insert_last(static_cast<void *>(element));
516 (*_actual_count.get())++;
|
517 mday 1.24 }
518
519
|
520 david.dillard 1.51 template<class L> void DQueue<L>::insert_last(L *element)
|
521 mday 1.24 {
|
522 david.dillard 1.49 if(element == 0)
523 return;
524 AutoMutex autoMut(*_mutex.get());
525 Base::insert_last(static_cast<void *>(element));
526 (*_actual_count.get())++;
|
527 mday 1.24 }
528
529
|
530 david.dillard 1.51 template<class L> void DQueue<L>::empty_list()
|
531 mday 1.24 {
|
532 david.dillard 1.49 if( Base::count() > 0)
533 {
534 AutoMutex autoMut(*_mutex.get());
535 Base::empty_list();
536 (*_actual_count.get()) = 0;
537 }
538 }
|
539 a.arora 1.44
|
540 mday 1.24
|
541 david.dillard 1.51 template<class L> L * DQueue<L>::remove_first()
|
542 david.dillard 1.49 {
543 L *ret = 0;
|
544 mday 1.24
|
545 david.dillard 1.49 if( _actual_count->value() )
546 {
547 AutoMutex autoMut(*_mutex.get());
548 ret = static_cast<L *>(Base::remove_first());
549 if( ret != 0 )
550 (*_actual_count.get())--;
551 }
|
552 a.arora 1.44
|
553 david.dillard 1.49 return ret;
|
554 mday 1.24 }
555
|
556 david.dillard 1.51 template<class L> L *DQueue<L>::remove_last()
|
557 david.dillard 1.49 {
558 L * ret = 0;
559 if( _actual_count->value() )
560 {
561 AutoMutex autoMut(*_mutex.get());
562 ret = static_cast<L *>(Base::remove_last());
563 if( ret != 0 )
564 (*_actual_count.get())--;
565 }
|
566 a.arora 1.44
|
567 david.dillard 1.49 return ret;
|
568 mday 1.24 }
569
|
570 david.dillard 1.51 template<class L> L *DQueue<L>::remove_no_lock(const void *key)
|
571 mday 1.24 {
|
572 david.dillard 1.49 if(key == 0 )
573 return 0;
574 if( pegasus_thread_self() != _mutex->get_owner())
575 throw Permission(pegasus_thread_self());
576
577 if (_actual_count->value() )
578 {
579 L *ret = static_cast<L *>(Base::next(0));
580 while( ret != 0 )
581 {
582 if (ret->operator==(key))
583 {
584 ret = static_cast<L *>(Base::remove(ret));
585 if( ret != 0 )
586 (*_actual_count.get())--;
587 return ret;
588 }
589
590 ret = static_cast<L *>(Base::next(static_cast<const void *>(ret)));
591 }
592 }
593 david.dillard 1.49
594 return 0 ;
|
595 mday 1.24 }
596
|
597 david.dillard 1.51 template<class L> L * DQueue<L>::remove_no_lock(const L *key)
|
598 mday 1.24 {
|
599 david.dillard 1.49 if(key == 0 )
600 return 0;
601 if( pegasus_thread_self() != _mutex->get_owner())
602 throw Permission(pegasus_thread_self());
603
604 if (_actual_count->value() )
605 {
606 L *ret = static_cast<L *>(Base::next(0));
607 while( ret != 0 )
608 {
609 if (ret->operator==(*key))
610 {
611 ret = static_cast<L *>(Base::remove(static_cast<const void *>(ret)));
612 if( ret != 0 )
613 (*_actual_count.get())--;
614 return ret;
615 }
616
617 ret = static_cast<L *>(Base::next(static_cast<const void *>(ret)));
618 }
619 }
620 david.dillard 1.49
621 return 0 ;
|
622 mday 1.24 }
623
624
|
625 david.dillard 1.51 template<class L> L * DQueue<L>::remove(const void *key)
|
626 mday 1.24 {
|
627 david.dillard 1.49 L *ret = 0;
628
629 if( _actual_count->value() > 0 )
630 {
631 AutoMutex autoMut(*_mutex.get());
632 ret = DQueue<L>::remove_no_lock(key);
633 }
|
634 a.arora 1.44
|
635 david.dillard 1.49 return(ret);
|
636 mday 1.24 }
637
|
638 david.dillard 1.51 template<class L>L *DQueue<L>::remove(const L *key)
|
639 mday 1.24 {
|
640 david.dillard 1.49 L *ret = 0;
641
642 if( _actual_count->value() > 0 )
643 {
644 AutoMutex autoMut(*_mutex.get());
645 ret = DQueue<L>::remove_no_lock(key);
646 }
647
648 return(ret);
|
649 mday 1.24 }
650
|
651 david.dillard 1.47 template<class L> L *DQueue<L>::reference(const L *key)
|
652 mday 1.24 {
|
653 david.dillard 1.49 if(key == 0)
654 return 0;
655
656 if( pegasus_thread_self() != _mutex->get_owner())
657 throw Permission(pegasus_thread_self());
658
659 if( _actual_count->value() )
660 {
661 L *ret = static_cast<L *>(Base::next(0));
662 while(ret != 0)
663 {
664 if(ret->operator==(*key))
665 return ret;
666 ret = static_cast<L *>(Base::next(static_cast<const void *>(ret)));
667 }
668 }
669
670 return(0);
|
671 mday 1.24 }
672
|
673 david.dillard 1.51 template<class L> L *DQueue<L>::reference(const void *key)
|
674 mday 1.24 {
|
675 david.dillard 1.49 if(key == 0)
676 return 0;
677
678 if( pegasus_thread_self() != _mutex->get_owner())
679 throw Permission(pegasus_thread_self());
680
681 if( _actual_count->value() )
682 {
683 L *ret = static_cast<L *>(Base::next(0));
684 while(ret != 0)
685 {
686 if(ret->operator==(key))
687 return ret;
688 ret = static_cast<L *>(Base::next(static_cast<const void *>(ret)));
689 }
690 }
691
692 return(0);
|
693 mday 1.24 }
694
|
695 david.dillard 1.51 template<class L> L * DQueue<L>::next( const void * ref)
|
696 mday 1.24 {
|
697 david.dillard 1.49 if (_mutex->get_owner() != pegasus_thread_self())
698 throw Permission(pegasus_thread_self()) ;
699
700 return static_cast<L *>(Base::next(ref));
|
701 mday 1.24 }
|
702 david.dillard 1.49
|
703 david.dillard 1.51 template<class L> L *DQueue<L>::prev( const void *ref)
|
704 mday 1.24 {
|
705 david.dillard 1.49 if (_mutex->get_owner() != pegasus_thread_self())
706 throw Permission(pegasus_thread_self());
707
708 return static_cast<L *>(Base::prev(ref));
709 }
710
|
711 david.dillard 1.51 template<class L> Boolean DQueue<L>::exists(const void *key)
|
712 david.dillard 1.49 {
713 if(key == 0)
714 return false;
715
716 Boolean ret = false;
717 if(_actual_count->value() > 0)
718 {
719 AutoMutex autoMut(*_mutex.get());
720 ret = (DQueue<L>::reference(key) != 0);
721 }
722
723 return(ret);
|
724 mday 1.24 }
725
|
726 david.dillard 1.51 template<class L> Boolean DQueue<L>::exists(const L *key)
|
727 mday 1.24 {
|
728 david.dillard 1.49 if(key == 0)
729 return false;
730
731 Boolean ret = false;
732 if(_actual_count->value() > 0)
733 {
734 AutoMutex autoMut(*_mutex.get());
735 ret = (DQueue<L>::reference(key) != 0);
736 }
737
738 return(ret);
|
739 mday 1.24 }
740
|
741 david.dillard 1.51 template<class L> void AsyncDQueue<L>::_insert_prep()
|
742 mday 1.24 {
|
743 david.dillard 1.49 if(_disallow->value() > 0)
744 {
745 unlock();
746 throw ListClosed();
747 }
748
749 _slot->lock_object(pegasus_thread_self());
750 while(true == is_full())
751 {
752 _slot->unlocked_wait(pegasus_thread_self());
753 if(_disallow->value() > 0)
754 {
755 unlock();
756 throw ListClosed();
757 }
758 }
|
759 mday 1.24 }
760
|
761 david.dillard 1.51 template<class L> void AsyncDQueue<L>::_insert_recover()
|
762 mday 1.24 {
|
763 david.dillard 1.49 _node->unlocked_signal(pegasus_thread_self());
764 (*_actual_count.get())++;
765 unlock();
|
766 mday 1.24 }
767
|
768 david.dillard 1.51 template<class L> void AsyncDQueue<L>::_unlink_prep()
|
769 mday 1.24 {
|
770 david.dillard 1.49 if(_disallow->value() > 0)
771 {
772 unlock();
773 throw ListClosed();
774 }
775 _node->lock_object(pegasus_thread_self());
776 while(true == is_empty())
777 {
778 _node->unlocked_wait(pegasus_thread_self());
779 if(_disallow->value() > 0)
780 {
781 unlock();
782 throw ListClosed();
783 }
784 }
|
785 mday 1.24 }
786
|
787 david.dillard 1.51 template<class L> void AsyncDQueue<L>::_unlink_recover()
|
788 mday 1.24 {
|
789 david.dillard 1.49 _slot->unlocked_signal(pegasus_thread_self());
790 (*_actual_count.get())--;
791 unlock();
|
792 mday 1.24 }
793
|
794 david.dillard 1.51 template<class L> L * AsyncDQueue<L>::_remove_no_lock(const void *key)
|
795 mday 1.24 {
|
796 david.dillard 1.49 if(_disallow->value() > 0)
797 {
798 unlock();
799 throw ListClosed();
800 }
801 if( pegasus_thread_self() != _cond->get_owner())
802 throw Permission(pegasus_thread_self());
803 L *ret = static_cast<L *>(Base::next(0));
804 while(ret != 0)
805 {
806 if(ret->operator==(key))
807 {
808 return static_cast<L *>(Base::remove(static_cast<const void *>(ret)));
809 }
810
811 ret = static_cast<L *>(Base::next(static_cast<const void *>(ret)));
812 }
813
814 return 0;
|
815 mday 1.24 }
816
|
817 david.dillard 1.51 template<class L> L *AsyncDQueue<L>::_remove_no_lock(const L *key)
|
818 mday 1.24 {
|
819 david.dillard 1.49 if(_disallow->value() > 0)
820 {
821 unlock();
822 throw ListClosed();
823 }
824 if( pegasus_thread_self() != _cond->get_owner())
825 throw Permission(pegasus_thread_self());
826 L *ret = static_cast<L *>(Base::next(0));
827 while(ret != 0)
828 {
829 if(ret->operator==(*key))
830 {
831 return static_cast<L *>(Base::remove(static_cast<const void *>(ret)));
832 }
833
834 ret = static_cast<L *>(Base::next(static_cast<const void *>(ret)));
835 }
836
837 return 0;
|
838 mday 1.24 }
839
840
|
841 david.dillard 1.51 template<class L> AsyncDQueue<L>::AsyncDQueue()
|
842 david.dillard 1.49 : Base(false)
|
843 mday 1.24 {
|
844 david.dillard 1.49
|
845 mday 1.24 }
846
|
847 david.dillard 1.51 template<class L> AsyncDQueue<L>::AsyncDQueue(Boolean head, Uint32 capacity)
848 : Base(head)
|
849 mday 1.24 {
|
850 david.dillard 1.49 if(head == true)
851 {
852 _cond.reset(new Mutex());
853 _slot.reset(new Condition(*_cond.get()));
854 _node.reset(new Condition(*_cond.get()));
855 _actual_count.reset(new AtomicInt(0));
856 _disallow.reset(new AtomicInt(0));
857 _capacity.reset(new AtomicInt(capacity));
858 }
|
859 mday 1.24 }
860
|
861 david.dillard 1.51 template<class L> AsyncDQueue<L>::~AsyncDQueue()
|
862 mday 1.24 {
|
863 david.dillard 1.49
|
864 mday 1.24 }
865
866
|
867 david.dillard 1.51 template<class L> void AsyncDQueue<L>::shutdown_queue()
|
868 mday 1.24 {
|
869 david.dillard 1.49 try
870 {
871 lock(pegasus_thread_self());
872 (*_disallow.get())++;
873 _node->disallow();
874 _node->unlocked_signal(pegasus_thread_self());
875 _node->unlocked_signal(pegasus_thread_self());
876 _slot->disallow();
877 _slot->unlocked_signal(pegasus_thread_self());
878 _slot->unlocked_signal(pegasus_thread_self());
879 unlock();
880 }
881 catch(const ListClosed &)
882 {
883 (*_disallow.get())++;
884 }
|
885 mday 1.24 }
886
|
887 david.dillard 1.51 template<class L> Boolean AsyncDQueue<L>::is_full()
|
888 mday 1.24 {
|
889 david.dillard 1.49 return false;
|
890 mday 1.29
|
891 david.dillard 1.49
892 if( _capacity->value() == 0 )
893 return false;
894
895 if(_actual_count->value() >= _capacity->value())
896 return true;
897 return false;
|
898 mday 1.24 }
899
|
900 david.dillard 1.51 template<class L> Boolean AsyncDQueue<L>::is_empty()
|
901 mday 1.24 {
|
902 david.dillard 1.49 if(_actual_count->value() == 0)
903 return true;
904 return false;
|
905 mday 1.24 }
906
907
|
908 david.dillard 1.51 template<class L> Boolean AsyncDQueue<L>::is_shutdown()
|
909 mday 1.24 {
|
910 david.dillard 1.49 if( _disallow->value() > 0)
911 return true;
912 return false;
|
913 mday 1.24 }
914
|
915 david.dillard 1.51 template<class L> void AsyncDQueue<L>::try_lock(PEGASUS_THREAD_TYPE myself)
|
916 mday 1.24 {
|
917 david.dillard 1.49 if(_disallow->value() > 0)
918 {
919 throw ListClosed();
920 }
921
922 _cond->try_lock(myself);
|
923 mday 1.24 }
924
|
925 david.dillard 1.51 template<class L> void AsyncDQueue<L>::lock(PEGASUS_THREAD_TYPE myself)
|
926 mday 1.24 {
|
927 david.dillard 1.49 if(_disallow->value() > 0)
928 {
929 throw ListClosed();
930 }
931 _cond->lock(myself);
|
932 mday 1.24 }
933
|
934 david.dillard 1.51 template<class L> void AsyncDQueue<L>::unlock()
|
935 mday 1.24 {
|
936 david.dillard 1.49 _cond->unlock();
|
937 mday 1.24 }
938
|
939 david.dillard 1.51 template<class L> void AsyncDQueue<L>::signal_slot()
|
940 david.dillard 1.49 {
941 AutoMutex autoMut(*_cond.get());
942 _slot->unlocked_signal(pegasus_thread_self());
|
943 mday 1.30 }
944
|
945 david.dillard 1.51 template<class L> void AsyncDQueue<L>::signal_node()
|
946 mday 1.30 {
|
947 david.dillard 1.49 AutoMutex autoMut(*_cond.get());
948 _node->unlocked_signal(pegasus_thread_self());
949 }
|
950 a.arora 1.44
|
951 david.dillard 1.51 template<class L> Condition *AsyncDQueue<L>::get_node_cond()
|
952 david.dillard 1.49 {
953 return _node.get() ;
|
954 mday 1.30 }
955
|
956 david.dillard 1.51 template<class L> Condition * AsyncDQueue<L>::get_slot_cond()
|
957 david.dillard 1.49 {
|
958 a.arora 1.50 return _slot.get();
|
959 david.dillard 1.49 }
960
|
961 david.dillard 1.51 template<class L> void AsyncDQueue<L>::wait_for_node()
|
962 mday 1.24 {
|
963 david.dillard 1.49 _unlink_prep();
|
964 mday 1.24 }
965
|
966 david.dillard 1.51 template<class L> void AsyncDQueue<L>::set_capacity(Uint32 capacity)
|
967 mday 1.24 {
|
968 david.dillard 1.49 lock(pegasus_thread_self());
969 *_capacity.get() = capacity;
970 unlock();
|
971 mday 1.24 }
972
|
973 david.dillard 1.51 template<class L> Uint32 AsyncDQueue<L>::get_capacity()
|
974 mday 1.24 {
|
975 david.dillard 1.49 return _capacity->value();
|
976 mday 1.24 }
977
|
978 david.dillard 1.51 template<class L> void AsyncDQueue<L>::insert_first(L *element)
|
979 mday 1.24 {
|
980 david.dillard 1.51 if(element != 0)
|
981 david.dillard 1.49 {
|
982 david.dillard 1.51 lock(pegasus_thread_self());
983 if(true == is_full())
984 {
985 unlock();
986 throw ListFull(_capacity->value());
987 }
988 Base::insert_first(static_cast<void *>(element));
989 _insert_recover();
|
990 david.dillard 1.49 }
|
991 mday 1.24 }
992
|
993 david.dillard 1.51 template<class L> void AsyncDQueue<L>::insert_first_wait(L *element)
|
994 mday 1.24 {
|
995 david.dillard 1.51 if(element != 0)
996 {
997 _insert_prep();
998 Base::insert_first(static_cast<void *>(element));
999 _insert_recover();
1000 }
|
1001 mday 1.24 }
1002
|
1003 david.dillard 1.51 template<class L> void AsyncDQueue<L>::insert_last(L *element)
|
1004 mday 1.24 {
|
1005 david.dillard 1.51 if(element != 0)
|
1006 david.dillard 1.49 {
|
1007 david.dillard 1.51 lock(pegasus_thread_self());
1008 if(true == is_full())
1009 {
1010 unlock();
1011 throw ListFull(_capacity->value());
1012 }
1013 Base::insert_last(static_cast<void *>(element));
1014 _insert_recover();
|
1015 david.dillard 1.49 }
|
1016 mday 1.24 }
1017
|
1018 david.dillard 1.51 template<class L> void AsyncDQueue<L>::insert_last_wait(L *element)
|
1019 mday 1.24 {
|
1020 david.dillard 1.52 if(element != 0)
|
1021 david.dillard 1.51 {
1022 _insert_prep();
1023 Base::insert_last(element);
1024 _insert_recover();
1025 }
|
1026 mday 1.24 }
1027
|
1028 david.dillard 1.51 template<class L> void AsyncDQueue<L>::empty_list()
|
1029 mday 1.24 {
|
1030 david.dillard 1.49 lock(pegasus_thread_self());
1031 Base::empty_list();
1032 (*_actual_count.get()) = 0;
1033 _slot->unlocked_signal(pegasus_thread_self());
1034 unlock();
|
1035 mday 1.24 }
1036
|
1037 david.dillard 1.51 template<class L> L *AsyncDQueue<L>::remove_first()
|
1038 mday 1.24 {
|
1039 mday 1.29
|
1040 david.dillard 1.49 lock(pegasus_thread_self());
1041 L *ret = static_cast<L *>(Base::remove_first());
1042 if(ret != 0)
1043 {
1044 _slot->unlocked_signal(pegasus_thread_self());
1045 (*_actual_count.get())--;
1046 }
1047 unlock();
1048 return ret;
|
1049 mday 1.24 }
1050
|
1051 david.dillard 1.51 template<class L> L *AsyncDQueue<L>::remove_first_wait()
|
1052 mday 1.24 {
|
1053 david.dillard 1.49 _unlink_prep();
1054 L *ret = static_cast<L *>(Base::remove_first());
1055 _unlink_recover();
1056 return ret;
|
1057 mday 1.24 }
1058
|
1059 david.dillard 1.51 template<class L> L *AsyncDQueue<L>::remove_last()
|
1060 mday 1.24 {
|
1061 david.dillard 1.49 lock(pegasus_thread_self());
|
1062 mday 1.29
|
1063 david.dillard 1.49 L *ret = static_cast<L *>(Base::remove_last());
1064 if(ret != 0)
1065 {
1066 (*_actual_count.get())--;
1067 _slot->unlocked_signal(pegasus_thread_self());
1068 }
1069 unlock();
1070 return ret;
|
1071 mday 1.24 }
1072
|
1073 david.dillard 1.51 template<class L> L *AsyncDQueue<L>::remove_last_wait()
|
1074 mday 1.24 {
|
1075 david.dillard 1.49 _unlink_prep();
1076 L *ret = static_cast<L *>(Base::remove_last());
1077 _unlink_recover();
1078 return ret;
|
1079 mday 1.24 }
1080
|
1081 david.dillard 1.51 template<class L> L *AsyncDQueue<L>::remove(const void *key)
|
1082 mday 1.24 {
|
1083 david.dillard 1.49 if(key == 0)
1084 return 0;
1085 lock(pegasus_thread_self());
1086
1087 L *ret = _remove_no_lock(key);
1088 if(ret != 0)
1089 {
1090 (*_actual_count.get())--;
1091 _slot->unlocked_signal(pegasus_thread_self());
1092 }
1093 unlock();
1094 return ret;
|
1095 mday 1.24 }
1096
|
1097 david.dillard 1.51 template<class L>L *AsyncDQueue<L>::remove(const L *key)
|
1098 mday 1.24 {
|
1099 david.dillard 1.49 if(key == 0)
1100 return 0;
1101 lock(pegasus_thread_self());
1102
1103 L *ret = _remove_no_lock(key);
1104 if(ret != 0)
1105 {
1106 (*_actual_count.get())--;
1107 _slot->unlocked_signal(pegasus_thread_self());
1108 }
1109 unlock();
1110 return ret;
|
1111 mday 1.24 }
1112
|
1113 david.dillard 1.51 template<class L> L *AsyncDQueue<L>::remove_no_lock(const void *key)
|
1114 mday 1.24 {
|
1115 david.dillard 1.49 if(_disallow->value() > 0)
1116 {
1117 unlock();
1118 throw ListClosed();
1119 }
1120
1121 if(key == 0)
1122 return 0;
1123
1124 L *ret = 0;
1125
1126 if(Base::count() > 0 )
1127 {
1128 ret = _remove_no_lock(key);
1129 if(ret != 0)
1130 {
1131 (*_actual_count.get())--;
1132 _slot->unlocked_signal(pegasus_thread_self());
1133 }
1134 }
1135
1136 david.dillard 1.49 return ret;
|
1137 mday 1.24 }
1138
1139
|
1140 david.dillard 1.51 template<class L> L *AsyncDQueue<L>::remove_no_lock(const L *key)
|
1141 mday 1.24 {
|
1142 david.dillard 1.49 if(_disallow->value() > 0)
1143 {
1144 unlock();
1145 throw ListClosed();
1146 }
1147
1148 if(key == 0)
1149 return 0;
1150
1151 L *ret = 0;
1152
1153 if(Base::count() > 0 )
1154 {
1155 ret = _remove_no_lock(key);
1156 if(ret != 0)
1157 {
1158 (*_actual_count.get())--;
1159 _slot->unlocked_signal(pegasus_thread_self());
1160 }
1161 }
1162
1163 david.dillard 1.49 return ret;
|
1164 mday 1.24 }
1165
|
1166 david.dillard 1.51 template<class L> L *AsyncDQueue<L>::remove_wait(const void *key)
|
1167 mday 1.24 {
|
1168 mday 1.29
|
1169 david.dillard 1.49 if(key == 0)
1170 return 0;
1171
1172 lock(pegasus_thread_self());
1173
1174 L *ret = _remove_no_lock(key);
1175 while( ret == 0 )
1176 {
1177 if(_disallow->value() > 0)
1178 {
1179 unlock();
1180 throw ListClosed();
1181 }
1182 _node->unlocked_wait(pegasus_thread_self());
1183 if(_disallow->value() > 0)
1184 {
1185 unlock();
1186 throw ListClosed();
1187 }
1188 ret = _remove_no_lock(key);
1189 }
1190 david.dillard 1.49 if(ret != 0)
1191 {
1192 (*_actual_count.get())--;
1193 _slot->unlocked_signal(pegasus_thread_self());
1194 }
1195 unlock();
1196 return ret;
|
1197 mday 1.24 }
1198
|
1199 david.dillard 1.51 template<class L> L *AsyncDQueue<L>::next(const L *ref)
|
1200 mday 1.24 {
1201 if( pegasus_thread_self() != _cond->get_owner())
|
1202 david.dillard 1.49 throw Permission(pegasus_thread_self());
1203
1204 return static_cast<L *>(Base::next( reinterpret_cast<const void *>(ref)));
|
1205 mday 1.24 }
1206
|
1207 david.dillard 1.51 template<class L> L *AsyncDQueue<L>::prev(const L *ref)
|
1208 mday 1.24 {
|
1209 david.dillard 1.49 if( pegasus_thread_self() != _cond->get_owner())
1210 throw Permission(pegasus_thread_self());
1211
1212 return static_cast<L *>(Base::prev( reinterpret_cast<const void *>(ref)));
|
1213 mday 1.24 }
1214
|
1215 david.dillard 1.51 template<class L> L *AsyncDQueue<L>::reference(const void *key)
|
1216 mday 1.24 {
|
1217 david.dillard 1.49 if(_disallow->value() > 0)
1218 {
1219 unlock();
1220 throw ListClosed();
1221 }
1222
1223 if( key == 0 )
1224 return 0;
1225
1226 if( pegasus_thread_self() != _cond->get_owner())
1227 throw Permission(pegasus_thread_self());
1228
1229 if(Base::count() > 0 )
1230 {
1231 L *ret = static_cast<L *>(Base::next(0));
1232 while(ret != 0)
1233 {
1234 if(ret->operator==(key))
1235 return ret;
1236 ret = static_cast<L *>(Base::next(static_cast<const void *>(ret)));
1237 }
1238 david.dillard 1.49 }
1239
1240 return(0);
|
1241 mday 1.24 }
1242
|
1243 david.dillard 1.51 template<class L> L *AsyncDQueue<L>::reference(const L *key)
|
1244 mday 1.24 {
|
1245 david.dillard 1.49 if(_disallow->value() > 0)
1246 {
1247 unlock();
1248 throw ListClosed();
1249 }
1250
1251 if(key == 0)
1252 return 0;
1253
1254 if( pegasus_thread_self() != _cond->get_owner())
1255 throw Permission(pegasus_thread_self());
1256
1257 if(Base::count() > 0 )
1258 {
1259 L *ret = static_cast<L *>(Base::next(0));
1260 while(ret != 0)
1261 {
1262 if(ret->operator==(*key))
1263 return ret;
1264 ret = static_cast<L *>(Base::next(static_cast<const void *>(ret)));
1265 }
1266 david.dillard 1.49 }
1267
1268 return(0);
1269 }
1270
|
1271 david.dillard 1.51 template<class L> Uint32 AsyncDQueue<L>::count()
|
1272 david.dillard 1.49 {
1273 return _actual_count->value();
|
1274 mday 1.24 }
1275
|
1276 david.dillard 1.51 template<class L> Uint32 AsyncDQueue<L>::size()
|
1277 david.dillard 1.49 {
1278 return _actual_count->value();
1279 }
|
1280 mday 1.24
|
1281 mike 1.2
1282 PEGASUS_NAMESPACE_END
1283
1284 #endif /* Pegasus_DQueue_h */
|