1 // BlockerPool.cpp 2 3 #include <new> 4 5 #include "AutoLocker.h" 6 #include "BlockerPool.h" 7 #include "Vector.h" 8 9 // BlockerVector 10 struct BlockerPool::BlockerVector : Vector<Blocker> { 11 }; 12 13 // constructor BlockerPool(int32 count)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 ~BlockerPool()26BlockerPool::~BlockerPool() 27 { 28 _Unset(); 29 } 30 31 // InitCheck 32 status_t InitCheck() const33BlockerPool::InitCheck() const 34 { 35 return fInitStatus; 36 } 37 38 // GetBlocker 39 Blocker GetBlocker()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 56 status_t PutBlocker(Blocker blocker)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 72 status_t _Init(int32 count)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 102 void _Unset()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