1// BlockerPool.cpp 2 3#include <new> 4 5#include "AutoLocker.h" 6#include "BlockerPool.h" 7#include "Vector.h" 8 9// BlockerVector 10struct BlockerPool::BlockerVector : Vector<Blocker> { 11}; 12 13// constructor 14BlockerPool::BlockerPool(int32 count) 15 : Locker("blocker pool"), 16 fFreeBlockersSemaphore(-1), 17 fBlockers(NULL), 18 fInitStatus(B_NO_INIT) 19{ 20 fInitStatus = _Init(count); 21 if (fInitStatus != B_OK) 22 _Unset(); 23} 24 25// destructor 26BlockerPool::~BlockerPool() 27{ 28 _Unset(); 29} 30 31// InitCheck 32status_t 33BlockerPool::InitCheck() const 34{ 35 return fInitStatus; 36} 37 38// GetBlocker 39Blocker 40BlockerPool::GetBlocker() 41{ 42 if (fInitStatus != B_OK) 43 return B_NO_INIT; 44 status_t error = acquire_sem(fFreeBlockersSemaphore); 45 if (error != B_OK) 46 return error; 47 AutoLocker<BlockerPool> _(this); 48 if (fInitStatus != B_OK) 49 return fInitStatus; 50 Blocker blocker = fBlockers->ElementAt(fBlockers->Count() - 1); 51 fBlockers->Erase(fBlockers->Count() - 1); 52 return blocker; 53} 54 55// PutBlocker 56status_t 57BlockerPool::PutBlocker(Blocker blocker) 58{ 59 status_t error = blocker.PrepareForUse(); 60 if (error != B_OK) 61 return error; 62 AutoLocker<BlockerPool> _(this); 63 if (fInitStatus != B_OK) 64 return fInitStatus; 65 error = fBlockers->PushBack(blocker); 66 if (error != B_OK) 67 return error; 68 return release_sem(fFreeBlockersSemaphore); 69} 70 71// _Init 72status_t 73BlockerPool::_Init(int32 count) 74{ 75 _Unset(); 76 AutoLocker<BlockerPool> locker(this); 77 if (!locker.IsLocked()) 78 return B_ERROR; 79 // create semaphore 80 fFreeBlockersSemaphore = create_sem(0, "blocker pool free blockers"); 81 if (fFreeBlockersSemaphore < 0) 82 return fFreeBlockersSemaphore; 83 // allocate blocker vector 84 fBlockers = new(std::nothrow) BlockerVector; 85 if (!fBlockers) 86 return B_NO_MEMORY; 87 fInitStatus = B_OK; 88 // create and add blockers 89 for (int32 i = 0; i < count; i++) { 90 Blocker blocker; 91 status_t error = blocker.InitCheck(); 92 if (error != B_OK) 93 return error; 94 error = PutBlocker(blocker); 95 if (error != B_OK) 96 return error; 97 } 98 return B_OK; 99} 100 101// _Unset 102void 103BlockerPool::_Unset() 104{ 105 AutoLocker<BlockerPool> locker(this); 106 if (fInitStatus == B_OK) 107 fInitStatus = B_NO_INIT; 108 delete fBlockers; 109 fBlockers = NULL; 110 if (fFreeBlockersSemaphore >= 0) 111 delete_sem(fFreeBlockersSemaphore); 112 fFreeBlockersSemaphore = -1; 113} 114 115