OSCL_EXPORT_REF void OsclTLSRegistry::cleanup(Oscl_DefAlloc &alloc, int32 &aError)
{
    TOsclTlsKey* pkey = NULL;
    aError = 0;
    sLock.Lock();

#if (OSCL_TLS_IS_KEYED)
    if (!iTlsKey)
    {
        aError = EPVErrorBaseNotInstalled;//No key!
        sLock.Unlock();
        return;
    }
    pkey = iTlsKey->iOsclTlsKey;
#endif

    //Cleanup this thread's registry
    registry_pointer_type registry = OSCL_STATIC_CAST(registry_pointer_type , TLSStorageOps::get_registry(pkey));
    if (!OSCL_TLS_REGISTRY_VALID(registry))
    {
        aError = EPVErrorBaseNotInstalled;//No registry!
        sLock.Unlock();
        return;
    }
    alloc.deallocate(registry);

    TLSStorageOps::save_registry(pkey, NULL, aError);
    if (aError)
    {
        sLock.Unlock();
        return;
    }

#if (OSCL_TLS_IS_KEYED)

    //Remove Tls key
    iTlsKey->iRefCnt--;
    if (iTlsKey->iRefCnt == 0)
    {
        //Deallocate key.
        OSCL_TLS_KEY_DELETE_FUNC(*pkey);
        alloc.deallocate(pkey);
        iTlsKey->~TlsKey();
        alloc.deallocate(iTlsKey);
        iTlsKey = NULL;
    }
#endif

    sLock.Unlock();
}
OSCL_EXPORT_REF void OsclSingletonRegistry::cleanup(Oscl_DefAlloc &alloc, int32 &aError)
{
    aError = 0;
    if (!iSingletonTable)
    {
        aError = EPVErrorBaseNotInstalled;//no table!
        return;
    }

    //decrement the ref count and cleanup when it reaches zero.
    iSingletonTable->iTableLock.Lock();
    iSingletonTable->iRefCount--;
    if (iSingletonTable->iRefCount == 0)
    {
        //cleanup
        iSingletonTable->iTableLock.Unlock();
        iSingletonTable->~SingletonTable();
        alloc.deallocate(iSingletonTable);
        iSingletonTable = NULL;
    }
    else
    {
        iSingletonTable->iTableLock.Unlock();
    }
}
OSCL_EXPORT_REF void CPVInterfaceProxy::Delete()
//called under app thread context
{
    Oscl_DefAlloc *alloc = this->iAlloc;
    bool default_alloc = (this->iAlloc == &this->iDefAlloc);
    this->~CPVInterfaceProxy();
    if (default_alloc)
    {
        OsclMemAllocator defalloc;
        defalloc.deallocate(this);
    }
    else
    {
        alloc->deallocate(this);
    }
}
OSCL_EXPORT_REF void OsclSingletonRegistry::initialize(Oscl_DefAlloc &alloc, int32 &aError)
{
    aError = 0;
    //Allocate the registry on the first init call
    //Note: there's some chance of thread contention here, since
    //thread lock isn't available until after this step.
    if (!iSingletonTable)
    {
        OsclAny* table = alloc.allocate(sizeof(SingletonTable));
        if (table)
            iSingletonTable = new(table) SingletonTable();
        else
        {
            aError = EPVErrorBaseOutOfMemory;
            return;
        }
    }

    //increment the ref count on each init.
    iSingletonTable->iTableLock.Lock();
    iSingletonTable->iRefCount++;
    iSingletonTable->iTableLock.Unlock();
}
OSCL_EXPORT_REF void OsclTLSRegistry::initialize(Oscl_DefAlloc &alloc, int32 &aError)
{
    TOsclTlsKey* pkey = NULL;
    aError = 0;

#if ( OSCL_TLS_IS_KEYED)
    //Allocate the table on the first init call.
    //Note there's some risk of thread contention here, since
    //the thread lock is not available until after this step.
    if (!iTlsKey)
    {
        OsclAny* table = alloc.allocate(sizeof(TlsKey));
        if (!table)
        {
            aError = EPVErrorBaseOutOfMemory;
            return;
        }

        //allocate space for key
        pkey = (TOsclTlsKey*)alloc.allocate(sizeof(TOsclTlsKey));
        if (!pkey)
        {
            aError = EPVErrorBaseOutOfMemory;
            alloc.deallocate(table);
            return;
        }

        //create key for this thread.
        if (!OSCL_TLS_KEY_CREATE_FUNC(*pkey))
        {
            aError = EPVErrorBaseSystemCallFailed;
            alloc.deallocate(pkey);
            alloc.deallocate(table);
            return;
        }

        iTlsKey = new(table) TlsKey();
        iTlsKey->iLock.Lock();
        iTlsKey->iRefCnt++;
        iTlsKey->iOsclTlsKey = pkey;
        iTlsKey->iLock.Unlock();
    }
    else
    {
        iTlsKey->iLock.Lock();
        iTlsKey->iRefCnt++;
        pkey = iTlsKey->iOsclTlsKey;
        iTlsKey->iLock.Unlock();
    }

#endif

    // allocate the space and save the pointer
    registry_pointer_type registry = OSCL_STATIC_CAST(registry_pointer_type,
                                     alloc.allocate(sizeof(registry_type) * OSCL_TLS_MAX_SLOTS));
    if (registry == 0)
    {
        aError = EPVErrorBaseOutOfMemory;
        return;
    }

    // initialize all TLSs to 0
    for (uint32 ii = 0; ii < OSCL_TLS_MAX_SLOTS; ii++)
        registry[ii] = 0;
    // initialize the magic number
    registry[OSCL_TLS_ID_MAGICNUM] = (OsclAny*)OSCL_TLS_MAGIC_NUMBER;

    // save it away
    TLSStorageOps::save_registry(pkey, registry, aError);
}