williamr@2: // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). williamr@2: // All rights reserved. williamr@2: // This component and the accompanying materials are made available williamr@2: // under the terms of the License "Symbian Foundation License v1.0" to Symbian Foundation members and "Symbian Foundation End User License Agreement v1.0" to non-members williamr@2: // which accompanies this distribution, and is available williamr@2: // at the URL "http://www.symbianfoundation.org/legal/licencesv10.html". williamr@2: // williamr@2: // Initial Contributors: williamr@2: // Nokia Corporation - initial contribution. williamr@2: // williamr@2: // Contributors: williamr@2: // williamr@2: // Description: williamr@2: // williamr@2: williamr@2: #ifndef __VERSITTLS_H__ williamr@2: #define __VERSITTLS_H__ williamr@2: williamr@2: // System includes williamr@2: #include williamr@2: #include williamr@2: williamr@2: #include williamr@2: williamr@2: class CVersitTimer; williamr@2: class CVersitAdditionalStorage; williamr@2: williamr@2: class CVersitTlsData : public CBase williamr@2: /** Versit thread local storage. williamr@2: williamr@2: This class provides a performance improvement by allowing a CVersitUnicodeUtils williamr@2: instance to be shared between parsers operating in the same thread, so that williamr@2: a new instance does not have to be created for each parser. A pointer to the williamr@2: unicode utilities object is held in thread local storage: a single word (32bits) williamr@2: of data. Each unicode utilities object is managed by an instance of this class. williamr@2: williamr@2: Every time a parser is created, CVersitParser::ConstructL() calls the williamr@2: CVersitTlsData constructor, and when the parser is destroyed the CVersitTlsData williamr@2: destructor is called. If a CVersitTlsData object exists, the constructor williamr@2: returns a pointer to it, otherwise a new one is constructed. The CVersitTlsData williamr@2: object is only destroyed when no more parsers refer to it: a count is kept, williamr@2: which is incremented every time the constructor is called and decremented each williamr@2: time the destructor is called, and the object is only destroyed when the count williamr@2: reaches zero. williamr@2: williamr@2: This class provides an additional major performance improvement williamr@2: if you are sequentially constructing and destructing multiple parsers. williamr@2: By default, when the count of parsers reaches zero, the thread local williamr@2: storage object is destroyed (even if the thread has not finished). However, williamr@2: by using the technique described below, the thread local storage object, and therefore williamr@2: the unicode utilities object, can be made to persist, significantly reducing williamr@2: the overhead of sequentially constructing and destructing parsers. williamr@2: williamr@2: The constructor needs to be called an extra time before creating any parsers, williamr@2: and the destructor needs to be called an extra time once the parsers have williamr@2: been destroyed. This has the effect of adding one to the reference count so williamr@2: that during all the parser construction and deletion the count never hits williamr@2: zero, which would trigger the TLS object's destruction. williamr@2: williamr@2: This can be implemented as follows: williamr@2: williamr@2: 1. Create a thread local storage data class instance as follows: williamr@2: @code williamr@2: CVersitTlsData* versitTLS = CVersitTlsData::VersitTlsDataL(); williamr@2: @endcode williamr@2: williamr@2: 2. Create and delete the parsers. williamr@2: williamr@2: 3. Delete the Thread Local Storage Data class instance: williamr@2: @code williamr@2: delete versitTLS; williamr@2: @endcode williamr@2: @publishedAll williamr@2: @released williamr@2: */ williamr@2: { williamr@2: friend class CVersitTimer; williamr@2: williamr@2: public: williamr@2: IMPORT_C static CVersitTlsData& VersitTlsDataL(); williamr@2: IMPORT_C static void CloseVersitTlsData(); williamr@2: IMPORT_C void VersitTlsDataClose(); williamr@2: williamr@2: public: williamr@2: inline CVersitUnicodeUtils& UnicodeUtils() williamr@2: /** Returns a pointer to the current Unicode utilities object. williamr@2: williamr@2: @return A pointer to the current Unicode utilities object. */ williamr@2: { return *iUnicodeUtils; } williamr@2: williamr@2: inline CVersitAdditionalStorage& AdditionalStorage() williamr@2: /** Returns a pointer to the additional property storage object. williamr@2: williamr@2: @return A pointer to the additional property storage. */ williamr@2: { williamr@2: return *iAdditionalStorage; williamr@2: } williamr@2: williamr@2: private: williamr@2: static CVersitTlsData* NewL(); williamr@2: void ConstructL(); williamr@2: ~CVersitTlsData(); williamr@2: williamr@2: private: williamr@2: TInt iRefCount; williamr@2: CVersitUnicodeUtils* iUnicodeUtils; williamr@2: CVersitAdditionalStorage* iAdditionalStorage; williamr@2: }; williamr@2: williamr@2: #endif