lowlevellibsandfws/pluginfw/Framework/frame/UnloadPolicy.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 02:01:42 +0200
changeset 0 e4d67989cc36
permissions -rw-r--r--
Revision: 201002 Kit: 201005

// Copyright (c) 1997-2009 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:
// Implementation of the CUnloadPolicy class
// 
//

/**
 @internalComponent
 @file
*/
#include <ecom/ecom.h>
#include <ecom/ecomerrorcodes.h>
#include <ecom/ecomresolverparams.h>
#include <ecom/implementationinformation.h>
#include "UnloadPolicy.h"
#include "TestUtilities.h"	// For __FILE__LINE__
#include "EComUidCodes.h"

// Design Note:
// 	Dll text is per process.
// 	RLibrary handles are per thread.
// 	Therefore, data related to each loaded dll is per thread so no need for any mutex on say
// 	the reference counter.

CUnloadPolicy* CUnloadPolicy::NewLC(const TEntry& aDllEntry)
	{
	CUnloadPolicy* self = new(ELeave) CUnloadPolicy();
	CleanupStack::PushL(self);
	self->ConstructL(aDllEntry);
	return self;
	}

// Default d'tor
CUnloadPolicy::~CUnloadPolicy()
	{
	// Make sure the library is unloaded
	iLibrary.Close();
	// Remove the instance variable
	delete iDllEntry;
	}

// Default c'tor
CUnloadPolicy::CUnloadPolicy()
	{
	// Do nothing here
	}

void CUnloadPolicy::ConstructL(const TEntry& aDllEntry)
	{
	iDllEntry = CEComEntry::NewL(aDllEntry.iName,aDllEntry.iType[1],aDllEntry.iType[2]);
	}

TUnloadPolicyStatus CUnloadPolicy::DecreaseReference()
	{
	// Already finished with this DLL OR
	// Note: There could be many clients per process	
	if (iReferencesInUseCount == 0 || --iReferencesInUseCount == 0)
		{
		return EDeleteMe;		
		}
	return EDontDeleteMe;
	}

void CUnloadPolicy::IncreaseReference()
	{
	++iReferencesInUseCount;
	}

TInt CUnloadPolicy::ReferenceCount() const
	{
	return iReferencesInUseCount;
	}

TLibraryFunction CUnloadPolicy::LoadDllAndReturnProxyL()
	{
	// Function at ordinal 1 is InstantiationMethodL()
	const TInt KImplementationGroupProxy = 1;

	// If we have already loaded the library
	if(iReferencesInUseCount > 0)
		{
		IncreaseReference();
		return iLibrary.Lookup(KImplementationGroupProxy);
		}
	const TDesC& libraryPath = iDllEntry->GetName();
	if(libraryPath.Length())
		{
		// Load up the specified library and its default method
		// Dynamically load DLL	
		User::LeaveIfError(iLibrary.Load(libraryPath, TUidType(KDynamicLibraryUid,iDllEntry->GetSecondUid(),iDllEntry->GetThirdUid())));
		// Add to the reference count now to keep the
		// library loaded for the instantiation call.
		// IF the client fails before instantiating an implementation
		// we can rely upon CEcomServerSession to correctly call
		// for an implementations reference to be removed.
		IncreaseReference();
		return iLibrary.Lookup(KImplementationGroupProxy);
		}
	return NULL;
	}	

const CEComEntry& CUnloadPolicy::DllEntryInformation() const
	{
	return *iDllEntry;
	}