/* * * @APPLE_LICENSE_HEADER_START@ * * Copyright (c) 1999-2001 Apple Computer, Inc. All Rights Reserved. The * contents of this file constitute Original Code as defined in and are * subject to the Apple Public Source License Version 1.2 (the 'License'). * You may not use this file except in compliance with the License. Please * obtain a copy of the License at http://www.apple.com/publicsource and * read it before using this file. * * This Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please * see the License for the specific language governing rights and * limitations under the License. * * * @APPLE_LICENSE_HEADER_END@ * */ /* File: OSQueue.cpp Contains: implements OSQueue class */ #include "OSQueue.h" OSQueue::OSQueue() : fLength(0) { fSentinel.fNext = &fSentinel; fSentinel.fPrev = &fSentinel; } void OSQueue::EnQueue(OSQueueElem* elem) { Assert(elem != NULL); if (elem->fQueue == this) return; Assert(elem->fQueue == NULL); elem->fNext = fSentinel.fNext; elem->fPrev = &fSentinel; elem->fQueue = this; fSentinel.fNext->fPrev = elem; fSentinel.fNext = elem; fLength++; } OSQueueElem* OSQueue::DeQueue() { if (fLength > 0) { OSQueueElem* elem = fSentinel.fPrev; Assert(fSentinel.fPrev != &fSentinel); elem->fPrev->fNext = &fSentinel; fSentinel.fPrev = elem->fPrev; elem->fQueue = NULL; fLength--; return elem; } else return NULL; } void OSQueue::Remove(OSQueueElem* elem) { Assert(elem != NULL); Assert(elem != &fSentinel); if (elem->fQueue == this) { elem->fNext->fPrev = elem->fPrev; elem->fPrev->fNext = elem->fNext; elem->fQueue = NULL; fLength--; } } #if OSQUEUETESTING Bool16 OSQueue::Test() { OSQueue theVictim; void *x = (void*)1; OSQueueElem theElem1(x); x = (void*)2; OSQueueElem theElem2(x); x = (void*)3; OSQueueElem theElem3(x); if (theVictim.GetHead() != NULL) return false; if (theVictim.GetTail() != NULL) return false; theVictim.EnQueue(&theElem1); if (theVictim.GetHead() != &theElem1) return false; if (theVictim.GetTail() != &theElem1) return false; OSQueueElem* theElem = theVictim.DeQueue(); if (theElem != &theElem1) return false; if (theVictim.GetHead() != NULL) return false; if (theVictim.GetTail() != NULL) return false; theVictim.EnQueue(&theElem1); theVictim.EnQueue(&theElem2); if (theVictim.GetHead() != &theElem1) return false; if (theVictim.GetTail() != &theElem2) return false; theElem = theVictim.DeQueue(); if (theElem != &theElem1) return false; if (theVictim.GetHead() != &theElem2) return false; if (theVictim.GetTail() != &theElem2) return false; theElem = theVictim.DeQueue(); if (theElem != &theElem2) return false; theVictim.EnQueue(&theElem1); theVictim.EnQueue(&theElem2); theVictim.EnQueue(&theElem3); if (theVictim.GetHead() != &theElem1) return false; if (theVictim.GetTail() != &theElem3) return false; theElem = theVictim.DeQueue(); if (theElem != &theElem1) return false; if (theVictim.GetHead() != &theElem2) return false; if (theVictim.GetTail() != &theElem3) return false; theElem = theVictim.DeQueue(); if (theElem != &theElem2) return false; if (theVictim.GetHead() != &theElem3) return false; if (theVictim.GetTail() != &theElem3) return false; theElem = theVictim.DeQueue(); if (theElem != &theElem3) return false; theVictim.EnQueue(&theElem1); theVictim.EnQueue(&theElem2); theVictim.EnQueue(&theElem3); OSQueueIter theIterVictim(&theVictim); if (theIterVictim.IsDone()) return false; if (theIterVictim.GetCurrent() != &theElem3) return false; theIterVictim.Next(); if (theIterVictim.IsDone()) return false; if (theIterVictim.GetCurrent() != &theElem2) return false; theIterVictim.Next(); if (theIterVictim.IsDone()) return false; if (theIterVictim.GetCurrent() != &theElem1) return false; theIterVictim.Next(); if (!theIterVictim.IsDone()) return false; if (theIterVictim.GetCurrent() != NULL) return false; theVictim.Remove(&theElem1); if (theVictim.GetHead() != &theElem2) return false; if (theVictim.GetTail() != &theElem3) return false; theVictim.Remove(&theElem1); if (theVictim.GetHead() != &theElem2) return false; if (theVictim.GetTail() != &theElem3) return false; theVictim.Remove(&theElem3); if (theVictim.GetHead() != &theElem2) return false; if (theVictim.GetTail() != &theElem2) return false; return true; } #endif void OSQueueIter::Next() { if (fCurrentElemP == fQueueP->GetTail()) fCurrentElemP = NULL; else fCurrentElemP = fCurrentElemP->Prev(); } OSQueueElem* OSQueue_Blocking::DeQueueBlocking(OSThread* inCurThread, SInt32 inTimeoutInMilSecs) { OSMutexLocker theLocker(&fMutex); if (fQueue.GetLength() == 0) fCond.Wait(&fMutex, inTimeoutInMilSecs); OSQueueElem* retval = fQueue.DeQueue(); return retval; } OSQueueElem* OSQueue_Blocking::DeQueue() { OSMutexLocker theLocker(&fMutex); OSQueueElem* retval = fQueue.DeQueue(); return retval; } void OSQueue_Blocking::EnQueue(OSQueueElem* obj) { { OSMutexLocker theLocker(&fMutex); fQueue.EnQueue(obj); } fCond.Signal(); }