www.pudn.com > MP3CORD.rar > queue.h


/*____________________________________________________________________________ 
         
        FreeAmp - The Free MP3 Player 
 
        Portions Copyright (C) 1998-1999 EMusic.com 
 
        This program is free software; you can redistribute it and/or modify 
        it under the terms of the GNU General Public License as published by 
        the Free Software Foundation; either version 2 of the License, or 
        (at your option) any later version. 
 
        This program is distributed in the hope that it will be useful, 
        but WITHOUT ANY WARRANTY; without even the implied warranty of 
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
        GNU General Public License for more details. 
 
        You should have received a copy of the GNU General Public License 
        along with this program; if not, write to the Free Software 
        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
         
        $Id: queue.h,v 1.7 1999/10/19 07:12:46 elrod Exp $ 
____________________________________________________________________________*/ 
 
#ifndef INCLUDED_QUEUE_H_ 
#define INCLUDED_QUEUE_H_ 
 
#include "config.h" 
#include "mutex.h" 
 
template 
class Queue { 
 
 public: 
    Queue(bool dwd = true); 
    ~Queue(); 
     
    T Read(); 
    T Peek(); 
    void  Clear(); 
    int32 Write(T &); 
    bool IsEmpty(); 
 
 private: 
    class QueueMember { 
        public: 
            QueueMember *m_behindMe; 
            T m_myMember; 
    }; 
 
    void GetLock(); 
    void ReleaseLock(); 
 
    QueueMember *m_head; 
    QueueMember *m_tail; 
    bool m_deleteWhenDone; 
    Mutex *m_myLock; 
  
}; 
 
 
template Queue::Queue(bool dwd) { 
    m_deleteWhenDone = dwd; 
    m_head = NULL; 
    m_tail = NULL; 
    m_myLock = new Mutex(); 
} 
 
template Queue::~Queue() { 
    GetLock(); 
    QueueMember *pQM = m_head; 
    QueueMember *next = NULL; 
    m_head = NULL; 
    m_tail = NULL; 
    ReleaseLock(); 
    while (pQM != NULL) { 
        next = pQM->m_behindMe; 
        if (m_deleteWhenDone) { 
            if (pQM->m_myMember) { 
                delete pQM->m_myMember; 
            } 
        } 
        delete pQM; 
        pQM = next; 
    } 
    if (m_myLock) { 
        delete m_myLock; 
    } 
} 
 
template T Queue::Read() { 
    GetLock(); 
    //cout << "queue:: read" << endl; 
    T rtnVal = NULL; 
    if (m_head) { 
        //cout << "queue:: read got m_head" << endl; 
        QueueMember *tmp = m_head; 
        rtnVal = tmp->m_myMember; 
        m_head = tmp->m_behindMe; 
        delete tmp; 
    } 
    if (m_head == NULL) { 
        // no m_tail anymore 
        m_tail = NULL; 
    } 
    //cout << "queue:: read ending" << endl; 
    ReleaseLock(); 
    return rtnVal; 
} 
 
template T Queue::Peek()  
{ 
    GetLock(); 
    T rtnVal = NULL; 
 
    if (m_head)  
    { 
        rtnVal = m_head->m_myMember; 
    } 
    ReleaseLock(); 
 
    return rtnVal; 
} 
 
template int32 Queue::Write(T &c) { 
    GetLock(); 
    QueueMember *pQM = new QueueMember(); 
    pQM->m_myMember = c; 
    pQM->m_behindMe = NULL; 
    if (m_tail) { 
        m_tail->m_behindMe = pQM; 
    } 
    m_tail = pQM; 
    if (m_head == NULL) { 
        // no m_head, this T we just pushed on is now the m_head 
        m_head = pQM; 
    } 
    ReleaseLock(); 
    return 0; 
} 
 
template void Queue::Clear()  
{ 
    GetLock(); 
 
    QueueMember *pQM = m_head; 
    QueueMember *next = NULL; 
    m_head = NULL; 
    m_tail = NULL; 
    ReleaseLock(); 
 
    while (pQM != NULL) { 
        next = pQM->m_behindMe; 
        if (m_deleteWhenDone) { 
            if (pQM->m_myMember) { 
                delete pQM->m_myMember; 
            } 
        } 
        delete pQM; 
        pQM = next; 
    } 
} 
 
 
template bool Queue::IsEmpty() { 
    assert(m_myLock); 
    return (m_head ? false : true); 
} 
 
template void Queue::GetLock() { 
    assert(m_myLock); 
    m_myLock->Acquire(WAIT_FOREVER); 
    return; 
} 
 
template void Queue::ReleaseLock() { 
    assert(m_myLock); 
    m_myLock->Release(); 
    return; 
} 
 
 
#endif //_QUEUE_H_