diff -r 000000000000 -r 671dee74050a searchengine/util/cpixtools/inc/public/cpixsyncpool.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/searchengine/util/cpixtools/inc/public/cpixsyncpool.h Mon Apr 19 14:40:16 2010 +0300 @@ -0,0 +1,235 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +#ifndef CPIXTOOLS_CPIXSYNCPOOL_H_ +#define CPIXTOOLS_CPIXSYNCPOOL_H_ + +#include +#include + +#include "cpixsynctools.h" + + +namespace Cpt +{ + + /** + * A template class for pooling items. There is always a given + * number of items kept around (either free or used), and clients + * can ask for more items, in which case those items are created + * on demand. + * + * NOTE: clients should always release the items back to the pool + * the moment they don't need them anymore, otherwise it will + * behave like a memory leak (even if it is technically not a + * memory leak). + * + * ITEM: must be default constructible and must have a public + * destructor. + */ + template + class SyncPool + { + private: + // + // private members + // + /** + * Stores the items that are free (at most minItemCount_ of + * them). + */ + std::list freeItems_; + + /** + * Stores the items that are used by clients. + */ + std::set usedItems_; + + const size_t minItemCount_; + + /** + * Protects freeItems_ and usedItems_ both. + */ + Mutex mutex_; + + public: + // + // public operators + // + /** + * Gets an item from the pool (either an existing unused one + * or a newly created one). Must be release()-ed + * eventually. Thread-safe implementation. + */ + ITEM * acquire(); + + + /** + * Releases an item back to the pool. The item itself may + * actually be destroyed, or just stored for future use, but + * the releasing client must not use it anymore. Thread-safe + * implementation. If the item being released has already been + * released or is unknown to the SyncPool, an exception is + * thrown (SyncExc). + */ + void release(ITEM * item); + + + // + // lifetime management + // + /** + * Constructs this item pool. + * + * @param minItemCount the number of items that will be kept + * around. This constructor does not actually create that many + * items up front, only on demand. + */ + SyncPool(size_t minItemCount); + + + /** + * Destructor. + */ + ~SyncPool(); + }; + +} + + + + +////////////////////////////////////////////////// +// +// +// I M P L E M E N T A T I O N +// +// +namespace Cpt +{ + + template + ITEM * SyncPool::acquire() + { + SyncRegion + sr(mutex_); + + ITEM + * rv = NULL; + + if (!freeItems_.empty()) + { + rv = freeItems_.front(); + freeItems_.pop_front(); + } + else + { + rv = new ITEM; + } + + usedItems_.insert(rv); + + return rv; + } + + + + template + void SyncPool::release(ITEM * item) + { + SyncRegion + sr(mutex_); + + if (usedItems_.find(item) == usedItems_.end()) + { + throw SyncExc("Releasing unknown item to SyncPool"); + } + + usedItems_.erase(item); + + if (freeItems_.size() == minItemCount_) + { + delete item; + } + else + { + freeItems_.push_back(item); + } + } + + + + template + SyncPool::SyncPool(size_t minItemCount) + : minItemCount_(minItemCount) + { + ; + } + + + + template + SyncPool::~SyncPool() + { + using namespace std; + + SyncRegion + sr(mutex_); + + // AR: Used on shutdown to test, whether pool items usages have leaked + if (!usedItems_.empty()) + { + throw SyncExc("Destroying SyncPool that has used items still"); + } + + { // free items + typename list::iterator + i = freeItems_.begin(), + end = freeItems_.end(); + + for (; i != end; ++i) + { + ITEM + * tmp = *i; + delete tmp; + } + + freeItems_.clear(); + } + + + { // used items + typename set::iterator + i = usedItems_.begin(), + end = usedItems_.end(); + + for (; i != end; ++i) + { + ITEM + * tmp = *i; + delete tmp; + } + + usedItems_.clear(); + } + + } + + +} + + +#endif CPIXTOOLS_CPIXSYNCPOOL_H_