int32 BufferPool::tryGetBuffer(uint32* bid) { int32 ret = 0; // lock mutex for reset MutexLocker ml(&_mutexReset); // decrement free buffers counter ret = _semFree.tryWait(); if (ret == FAILURE) return FAILURE; DataBuf* buf = (DataBuf*) _psFree.pop(); if (!buf) { puts("Critical: null buffer in pool"); return FAILURE; } *bid = buf->getBID(); // increment used buffers counter _semUsed.post(); // ok return SUCCESS; }
uint32 BufferPool::getBuffer(void) { DataBuf* buf = NULL; // lock mutex for reset MutexLocker ml(&_mutexReset); // decrement free buffers counter _semFree.wait(); // get bid from stack buf = (DataBuf *) _psFree.pop(); // check if there are no more free buffers if (!buf) { fprintf(stderr, "BufferPool: NO MORE FREE BUFFERS...\n"); return 0; } // increment used buffers counter _semUsed.post(); // return this bid return buf->getBID(); }
void BufferPool::reset(void) { DataBuf* buf = NULL; int32 ret = 0; // lock mutex for reset MutexLocker ml(&_mutexReset); // empty buffers stack for (uint32 j = 0; j < _bcount; j++) { buf = (DataBuf *) _psFree.pop(); if (!buf) break; UOSUTIL_DOUT(("Get buffer from the stack: %u\n", buf->getBID())); } // reset "used" semaphore while ((ret = _semUsed.tryWait()) != FAILURE) UOSUTIL_DOUT(("Waiting on semaphore \"used\"\n")); // reset "free" semaphore while ((ret = _semFree.tryWait()) != FAILURE) UOSUTIL_DOUT(("Waiting on semaphore \"free\"\n")); // put all buffers in the buffers stack for (uint32 i = 0; i < _bcount; i++) { // reset buffer _bufs[i]->setInUse(false); _bufs[i]->setCount(0); // push buffer pointer into the "free buffers" stack _psFree.push(_bufs[i]); // DEBUG UOSUTIL_DOUT(("Buffer %u pushed.\n", _bufs[i]->getBID())); } // reset "free" semaphore for (uint32 k = 0; k < _bcount; k++) { UOSUTIL_DOUT(("Posting semaphore \"free\" (%u)\n", k)); _semFree.post(); } }
BufferPool::~BufferPool(void) { uint32 bid = 0, i = 0; uint32 wait = 10, bc = 0; MutexLocker ml(&_mutexReset); /* * Here we must free the unlocked buffers first, * then wait some time for further buffers that will * be freed by worker threads. */ while (bc < _bcount && i++ < wait) { DataBuf* buf = (DataBuf*) _psFree.pop(); if (buf) { // get buffer id bid = buf->getBID(); // free selected buffer delete _bufs[bid]; // reset pointer _bufs[bid] = NULL; // count freed buffers bc++; } else { // wait some time Thread::sleep(50); } } /* * Timeout expired, so check which buffers are not * returned home. */ for (i = 0; i < _bcount; i++) { if (_bufs[i]) { // DEBUG UOSUTIL_DOUT(("BufferPool: Buffer %d is NOT NULL\n", i)); if (!_bufs[i]->isInUse()) { // DEBUG UOSUTIL_DOUT(("BufferPool: Buffer %d is NOT IN USE\n", i)); UOSUTIL_DOUT(("BufferPool: Buffer %d will be DELETED\n", i)); delete _bufs[i]; } else { // DEBUG UOSUTIL_DOUT(("BufferPool: Buffer %d is IN USE: leaked\n", i)); } } else { // DEBUG UOSUTIL_DOUT(("BufferPool: Buffer %d is NULL, ignored\n", i)); } } /* * Delete other objects. */ delete[] _bufs; }