/* * Copyright (C) 2007-2023 Xagasoft, All rights reserved. * * This file is part of the libbu++ library and is released under the * terms of the license contained in the file LICENSE. */ #ifndef BU_SYNCHRO_HEAP_H #define BU_SYNCHRO_HEAP_H #include "bu/heap.h" #include "bu/mutex.h" #include "bu/condition.h" namespace Bu { template, typename itemalloc=std::allocator > class SynchroHeap { public: SynchroHeap() { } virtual ~SynchroHeap() { } void enqueue( item i ) { imData.lock(); hData.enqueue( i ); icBlock.signal(); imData.unlock(); } item dequeue( bool bBlock=false ) { imData.lock(); if( hData.isEmpty() ) { imData.unlock(); if( bBlock ) { icBlock.lock(); while( hData.isEmpty() ) icBlock.wait(); imData.lock(); try { item iRet = hData.dequeue(); imData.unlock(); icBlock.unlock(); return iRet; } catch(...) { imData.unlock(); icBlock.unlock(); throw; } } throw HeapException("Heap empty."); } else { try { item iRet = hData.dequeue(); imData.unlock(); return iRet; } catch(...) { imData.unlock(); throw; } } } item dequeue( int iSec, int iUSec ) { imData.lock(); if( hData.isEmpty() ) { imData.unlock(); icBlock.lock(); icBlock.wait( iSec, iUSec ); imData.lock(); try { item iRet = hData.dequeue(); imData.unlock(); icBlock.unlock(); return iRet; } catch(...) { imData.unlock(); icBlock.unlock(); throw; } } else { try { item iRet = hData.dequeue(); imData.unlock(); return iRet; } catch(...) { imData.unlock(); throw; } } } bool isEmpty() { imData.lock(); bool bRet = hData.isEmpty(); imData.unlock(); return bRet; } int getSize() { imData.lock(); int iRet = hData.getSize(); imData.unlock(); return iRet; } void unblockAll() { icBlock.lock(); icBlock.broadcast(); icBlock.unlock(); } private: Heap< item, cmpfunc, itemalloc > hData; Mutex imData; Condition icBlock; }; }; #endif