1 karl 1.54 //%2006////////////////////////////////////////////////////////////////////////
|
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 karl 1.54 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.2 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
|
20 karl 1.54 //
|
21 mike 1.2 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 // Author: Mike Day (mdday@us.ibm.com)
33 //
|
34 a.arora 1.42 // Modified By: Amit K Arora, IBM (amita@in.ibm.com) for PEP#101
|
35 a.arora 1.44 // Alagaraja Ramasubramanian (alags_raj@in.ibm.com) for Bug#1090
|
36 a.arora 1.46 // Amit K Arora, IBM (amita@in.ibm.com) for Bug#2322
|
37 david.dillard 1.49 // David Dillard, VERITAS Software Corp.
38 // (david.dillard@veritas.com)
|
39 a.arora 1.50 // Amit K Arora, IBM (amita@in.ibm.com) for Bug#2960
|
40 mike 1.2 //
41 //%/////////////////////////////////////////////////////////////////////////////
42
43 #ifndef Pegasus_DQueue_h
44 #define Pegasus_DQueue_h
45
46 #include <Pegasus/Common/IPC.h>
|
47 kumpf 1.36 #include <Pegasus/Common/Linkage.h>
|
48 a.arora 1.42 #include <Pegasus/Common/AutoPtr.h>
|
49 mike 1.2
50 PEGASUS_NAMESPACE_BEGIN
51
|
52 tony 1.38 template<class L> class DQueue : public internal_dq
|
53 mike 1.2 {
|
54 david.dillard 1.49 public:
55 static void *operator new(size_t size);
56 static void operator delete(void *dead, size_t size);
57
58 private:
59 AutoPtr<Mutex> _mutex; //PEP101
60 AutoPtr<AtomicInt> _actual_count;
61 DQueue *_dq_next;
62 static DQueue<L> *_headOfFreeList;
|
63 mike 1.55 enum { BLOCK_SIZE = 200 };
|
64 david.dillard 1.49 static Mutex _alloc_mut;
65
66 public:
67 typedef internal_dq Base;
|
68 david.dillard 1.51 DQueue();
|
69 david.dillard 1.49 DQueue(Boolean head);
70
71 virtual ~DQueue();
72
|
73 david.dillard 1.51 /**
74 @exception IPCException Indicates an IPC error occurred.
75 */
76 void lock();
77
78 /**
79 @exception IPCException Indicates an IPC error occurred.
80 */
81 void unlock();
82
83 /**
84 @exception IPCException Indicates an IPC error occurred.
85 */
86 void try_lock();
87
88 /**
89 @exception IPCException Indicates an IPC error occurred.
90 */
91 void insert_first_no_lock(L *element);
92
93 /**
94 david.dillard 1.51 @exception IPCException Indicates an IPC error occurred.
95 */
96 void insert_first(L *element);
97
98 /**
99 @exception IPCException Indicates an IPC error occurred.
100 */
101 void insert_last_no_lock(L *element);
102
103 /**
104 @exception IPCException Indicates an IPC error occurred.
105 */
106 void insert_last(L *element);
107
108 /**
109 @exception IPCException Indicates an IPC error occurred.
110 */
111 void empty_list();
112
113 /**
114 @exception IPCException Indicates an IPC error occurred.
115 david.dillard 1.51 */
116 L *remove_first();
117
118 /**
119 @exception IPCException Indicates an IPC error occurred.
120 */
121 L *remove_last();
122
123 /**
124 @exception IPCException Indicates an IPC error occurred.
125 */
126 L *remove_no_lock(const void *key);
127
128 /**
129 @exception IPCException Indicates an IPC error occurred.
130 */
131 L *remove_no_lock(const L *key);
132
133 /**
134 @exception IPCException Indicates an IPC error occurred.
135 */
136 david.dillard 1.51 L *remove(const void *key);
137
138 /**
139 @exception IPCException Indicates an IPC error occurred.
140 */
141 L *remove(const L *key);
142
143 /**
144 @exception IPCException Indicates an IPC error occurred.
145 */
146 L *reference(const void *key);
147
|
148 david.dillard 1.49 L *reference(const L *key);
|
149 david.dillard 1.51
150 /**
151 @exception IPCException Indicates an IPC error occurred.
152 */
153 L *next(const void * ref);
154
155 /**
156 @exception IPCException Indicates an IPC error occurred.
157 */
158 L *prev(const void *ref);
159
160 /**
161 @exception IPCException Indicates an IPC error occurred.
162 */
163 Boolean exists(const void *key);
164
165 /**
166 @exception IPCException Indicates an IPC error occurred.
167 */
168 Boolean exists(const L *key);
|
169 david.dillard 1.49
|
170 mike 1.53 Uint32 count(void) { return _actual_count->get() ; }
171 Uint32 size(void) { return _actual_count->get() ; }
|
172 mike 1.2 } ;
173
|
174 david.dillard 1.49
|
175 mday 1.20
|
176 tony 1.38 template<class L> class AsyncDQueue: public internal_dq
|
177 mike 1.2 {
|
178 mday 1.20
|
179 david.dillard 1.49 public:
180 static void * operator new(size_t size);
181 static void operator delete(void *, size_t);
182
183 private: // asyncdqueue
184 AutoPtr<Mutex> _cond;
185 AutoPtr<Condition> _slot;
186 AutoPtr<Condition> _node;
187 AutoPtr<AtomicInt> _actual_count;
188 AutoPtr<AtomicInt> _disallow;
189 AutoPtr<AtomicInt> _capacity;
190 AsyncDQueue *_dq_next;
191
192 static AsyncDQueue *_headOfFreeList;
|
193 mike 1.55 enum { BLOCK_SIZE = 20 };
|
194 david.dillard 1.51 static Mutex _alloc_mut;
|
195 david.dillard 1.49
|
196 david.dillard 1.51 /**
197 @exception IPCException Indicates an IPC error occurred.
198 */
199 void _insert_prep();
200
201 /**
202 @exception IPCException Indicates an IPC error occurred.
203 */
204 void _insert_recover();
205
206 /**
207 @exception IPCException Indicates an IPC error occurred.
208 */
209 void _unlink_prep();
210
211 /**
212 @exception IPCException Indicates an IPC error occurred.
213 */
214 void _unlink_recover();
215
216 /**
217 david.dillard 1.51 @exception IPCException Indicates an IPC error occurred.
218 */
219 L *_remove_no_lock(const void *key);
220
221 /**
222 @exception IPCException Indicates an IPC error occurred.
223 */
224 L *_remove_no_lock(const L *key);
|
225 david.dillard 1.49
226 public:
227 typedef internal_dq Base;
228
|
229 david.dillard 1.51 AsyncDQueue() ;
230 AsyncDQueue(Boolean head, Uint32 capacity);
231 virtual ~AsyncDQueue();
232 void shutdown_queue();
233 Boolean is_full();
234 Boolean is_empty();
235 Boolean is_shutdown();
236
237 /**
238 @exception IPCException Indicates an IPC error occurred.
239 */
240 void try_lock(PEGASUS_THREAD_TYPE myself);
241
242 /**
243 @exception IPCException Indicates an IPC error occurred.
244 */
245 void lock(PEGASUS_THREAD_TYPE myself);
246
|
247 david.dillard 1.49 void unlock(void);
|
248 david.dillard 1.51
249 /**
250 @exception IPCException Indicates an IPC error occurred.
251 */
252 void signal_slot(void);
253
254 /**
255 @exception IPCException Indicates an IPC error occurred.
256 */
257 void signal_node();
258
259 Condition *get_node_cond();
260 Condition *get_slot_cond();
261
262 /**
263 @exception IPCException Indicates an IPC error occurred.
264 */
265 void wait_for_node();
266
267 /**
268 @exception IPCException Indicates an IPC error occurred.
269 david.dillard 1.51 */
270 void set_capacity(Uint32 capacity);
271
272 Uint32 get_capacity();
273
274 /**
275 @exception IPCException Indicates an IPC error occurred.
276 */
277 void insert_first(L *element);
278
279 /**
280 @exception IPCException Indicates an IPC error occurred.
281 */
282 void insert_first_wait(L *element);
283
284 /**
285 @exception IPCException Indicates an IPC error occurred.
286 */
287 void insert_last(L *element);
288
289 /**
290 david.dillard 1.51 @exception IPCException Indicates an IPC error occurred.
291 */
292 void insert_last_wait(L *element);
293
294 /**
295 @exception IPCException Indicates an IPC error occurred.
296 */
297 void empty_list();
298
299 /**
300 @exception IPCException Indicates an IPC error occurred.
301 */
302 L *remove_first();
303
304 /**
305 @exception IPCException Indicates an IPC error occurred.
306 */
307 L *remove_first_wait();
308
309 /**
310 @exception IPCException Indicates an IPC error occurred.
311 david.dillard 1.51 */
312 L *remove_last();
313
314 /**
315 @exception IPCException Indicates an IPC error occurred.
316 */
317 L *remove_last_wait();
318
319 /**
320 @exception IPCException Indicates an IPC error occurred.
321 */
322 L *remove(const void *key);
323
324 /**
325 @exception IPCException Indicates an IPC error occurred.
326 */
327 L *remove(const L *key);
328
329 /**
330 @exception IPCException Indicates an IPC error occurred.
331 */
332 david.dillard 1.51 L *remove_no_lock(const void *key);
333
334 /**
335 @exception IPCException Indicates an IPC error occurred.
336 */
337 L *remove_no_lock(const L *key);
338
339 /**
340 @exception IPCException Indicates an IPC error occurred.
341 */
342 L *remove_wait(const void *key);
343
344 /**
345 @exception IPCException Indicates an IPC error occurred.
346 */
347 L *next(const L *ref);
348
349 /**
350 @exception IPCException Indicates an IPC error occurred.
351 */
352 L *prev(const L *ref);
353 david.dillard 1.51
354 /**
355 @exception IPCException Indicates an IPC error occurred.
356 */
357 L *reference(const void *key);
358
359 /**
360 @exception IPCException Indicates an IPC error occurred.
361 */
362 L *reference(const L *key);
363 Uint32 count();
364 Uint32 size();
|
365 mike 1.2 };
|
366 david.dillard 1.49
|
367 keith.petley 1.39 template<class L> DQueue<L> * DQueue<L>::_headOfFreeList = 0;
|
368 mday 1.25 template<class L> Mutex DQueue<L>::_alloc_mut;
369
|
370 mday 1.29 template<class L> void *DQueue<L>::operator new(size_t size)
371 {
|
372 david.dillard 1.49 if (size != sizeof(DQueue<L>))
373 return ::operator new(size);
374
375 AutoMutex autoMut(_alloc_mut);
376
377 DQueue<L> *p = _headOfFreeList;
378 if(p)
379 _headOfFreeList = p->_dq_next;
380 else
381 {
382 DQueue<L> * newBlock =
383 static_cast<DQueue<L> *>(::operator new(BLOCK_SIZE * sizeof(DQueue<L>)));
384 int i;
385 for( i = 1; i < BLOCK_SIZE - 1; ++i)
386 newBlock[i]._dq_next = &newBlock[i + 1];
387 newBlock[BLOCK_SIZE - 1]._dq_next = 0;
388
389 p = newBlock;
390 _headOfFreeList = &newBlock[1];
391 }
|
392 a.arora 1.44
|
393 david.dillard 1.49
394 return p;
|
395 mday 1.29 }
396
397 template<class L> void DQueue<L>::operator delete(void *dead, size_t size)
398 {
|
399 david.dillard 1.49 if(dead == 0)
400 return;
401 if(size != sizeof(DQueue<L>))
402 {
403 ::operator delete(dead);
404 return;
405 }
406 DQueue<L> *p = static_cast<DQueue<L> *>(dead);
407 AutoMutex autoMut(_alloc_mut);
408 p->_dq_next = _headOfFreeList;
409 _headOfFreeList = p;
|
410 mday 1.29 }
|
411 mday 1.25
|
412 keith.petley 1.39 template<class L> AsyncDQueue<L> * AsyncDQueue<L>::_headOfFreeList =0;
|
413 mday 1.25 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 mike 1.53 if( _actual_count->get() )
|
546 david.dillard 1.49 {
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 mike 1.53 if( _actual_count->get() )
|
560 david.dillard 1.49 {
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 mike 1.53 if (_actual_count->get() )
|
578 david.dillard 1.49 {
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
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 mike 1.53 if (_actual_count->get() )
|
605 david.dillard 1.49 {
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
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 mike 1.53 if( _actual_count->get() > 0 )
|
630 david.dillard 1.49 {
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 mike 1.53 if( _actual_count->get() > 0 )
|
643 david.dillard 1.49 {
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 mike 1.53 if( _actual_count->get() )
|
660 david.dillard 1.49 {
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 mike 1.53 if( _actual_count->get() )
|
682 david.dillard 1.49 {
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 mike 1.53 if(_actual_count->get() > 0)
|
718 david.dillard 1.49 {
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 mike 1.53 if(_actual_count->get() > 0)
|
733 david.dillard 1.49 {
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 mike 1.53 if(_disallow->get() > 0)
|
744 david.dillard 1.49 {
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 mike 1.53 if(_disallow->get() > 0)
|
754 david.dillard 1.49 {
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 mike 1.53 if(_disallow->get() > 0)
|
771 david.dillard 1.49 {
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 mike 1.53 if(_disallow->get() > 0)
|
780 david.dillard 1.49 {
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 mike 1.53 if(_disallow->get() > 0)
|
797 david.dillard 1.49 {
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 mike 1.53 if(_disallow->get() > 0)
|
820 david.dillard 1.49 {
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 mike 1.53 if( _capacity->get() == 0 )
|
893 david.dillard 1.49 return false;
894
|
895 mike 1.53 if(_actual_count->get() >= _capacity->get())
|
896 david.dillard 1.49 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 mike 1.53 if(_actual_count->get() == 0)
|
903 david.dillard 1.49 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 mike 1.53 if( _disallow->get() > 0)
|
911 david.dillard 1.49 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 mike 1.53 if(_disallow->get() > 0)
|
918 david.dillard 1.49 {
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 mike 1.53 if(_disallow->get() > 0)
|
928 david.dillard 1.49 {
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 mike 1.53 return _capacity->get();
|
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 mike 1.53 throw ListFull(_capacity->get());
|
987 david.dillard 1.51 }
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 mike 1.53 throw ListFull(_capacity->get());
|
1012 david.dillard 1.51 }
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 mike 1.53 if(_disallow->get() > 0)
|
1116 david.dillard 1.49 {
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 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 mike 1.53 if(_disallow->get() > 0)
|
1143 david.dillard 1.49 {
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 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 mike 1.53 if(_disallow->get() > 0)
|
1178 david.dillard 1.49 {
1179 unlock();
1180 throw ListClosed();
1181 }
1182 _node->unlocked_wait(pegasus_thread_self());
|
1183 mike 1.53 if(_disallow->get() > 0)
|
1184 david.dillard 1.49 {
1185 unlock();
1186 throw ListClosed();
1187 }
1188 ret = _remove_no_lock(key);
1189 }
1190 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 mike 1.53 if(_disallow->get() > 0)
|
1218 david.dillard 1.49 {
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 }
1239 david.dillard 1.49
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 mike 1.53 if(_disallow->get() > 0)
|
1246 david.dillard 1.49 {
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 }
1267 david.dillard 1.49
1268 return(0);
1269 }
1270
|
1271 david.dillard 1.51 template<class L> Uint32 AsyncDQueue<L>::count()
|
1272 david.dillard 1.49 {
|
1273 mike 1.53 return _actual_count->get();
|
1274 mday 1.24 }
1275
|
1276 david.dillard 1.51 template<class L> Uint32 AsyncDQueue<L>::size()
|
1277 david.dillard 1.49 {
|
1278 mike 1.53 return _actual_count->get();
|
1279 david.dillard 1.49 }
|
1280 mday 1.24
|
1281 mike 1.2
1282 PEGASUS_NAMESPACE_END
1283
1284 #endif /* Pegasus_DQueue_h */
|