(file) Return to DQueue.h CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

   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 */

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2