os/ossrv/genericopenlibs/openenvcore/ewsd/src/ewsd.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/genericopenlibs/openenvcore/ewsd/src/ewsd.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,281 @@
     1.4 +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// Name        : ewsd.cpp
    1.18 +// Part of     : ewsd library
    1.19 +// Contains the definitions of the APIs of the emulator WSD library 
    1.20 +//
    1.21 +
    1.22 +
    1.23 +
    1.24 +#ifdef __WINSCW__
    1.25 +
    1.26 +#include <e32std.h>
    1.27 +#include <windows.h>
    1.28 +
    1.29 +// Constant declarations
    1.30 +const TInt KMaxNumberOfProcesses = 100;
    1.31 +const TInt KMaxNumberOfLibraries = 50;
    1.32 +
    1.33 +// Panic strings
    1.34 +_LIT(KMutexGetFailure, "WSD mutex get failed");
    1.35 +_LIT(KMutexReleaseFailure, "WSD mutex release failed");
    1.36 +
    1.37 +// Mutex name
    1.38 +unsigned short KMutexName[] = 
    1.39 +	{
    1.40 +		'E', 'W', 'S', 'D', 'M', 'u', 't', 'e', 'x'
    1.41 +	};
    1.42 +
    1.43 +// LOCAL STRUCTURE DECLARATIONS
    1.44 +
    1.45 +// Data structure to store the WSD info associated with a particular DLL
    1.46 +struct TDllData
    1.47 +	{
    1.48 +	TUid  iLibraryUid;
    1.49 +	TAny* iPtr;
    1.50 +	};
    1.51 +
    1.52 +// Data structure to store the DLL information associated with a process
    1.53 +struct TWsdNode
    1.54 +	{
    1.55 +	TProcessId  iPid;
    1.56 +	TInt  		iFirstUnusedSlot;
    1.57 +	struct TDllData iDllData[KMaxNumberOfLibraries];
    1.58 +	};
    1.59 +	
    1.60 +// WSD array variables
    1.61 +struct TWsdNode WsdArray[KMaxNumberOfProcesses];
    1.62 +TInt LastUsedProcessSlot = -1;
    1.63 +
    1.64 +// LOCAL FUNCTION DECLARATIONS
    1.65 +
    1.66 +LOCAL_C TInt CleanupDeadProcessSlots();
    1.67 +LOCAL_C void StorePls(const TInt& aProcessSlot, const TInt& aLibrarySlot, TAny* aPls, const TUid& aLibraryUid);  
    1.68 +	
    1.69 +// EXPORTED FUNCTION DEFINITIONS
    1.70 +
    1.71 +EXPORT_C TAny* CheckPls(const TUid& aLibraryUid)
    1.72 +	{
    1.73 +	TProcessId procId = RProcess().Id();
    1.74 +	
    1.75 +	for (TInt i = 0; i <= LastUsedProcessSlot; ++i)
    1.76 +		{
    1.77 +		if (WsdArray[i].iPid == procId)
    1.78 +			{
    1.79 +			// This process has a slot in the WsdArray - now check
    1.80 +			// whether its DLL array contains the specified library
    1.81 +			TInt firstUnused = WsdArray[i].iFirstUnusedSlot;
    1.82 +			for (TInt j = 0; j < firstUnused; ++j)	
    1.83 +				{
    1.84 +				if (aLibraryUid == WsdArray[i].iDllData[j].iLibraryUid)
    1.85 +					{
    1.86 +					// The specified library is present so return the PLS object
    1.87 +					return WsdArray[i].iDllData[j].iPtr;
    1.88 +					}
    1.89 +				}
    1.90 +			break;
    1.91 +			}
    1.92 +		}
    1.93 +	
    1.94 +	// The PLS object hasn't yet been stored	
    1.95 +	return NULL;
    1.96 +	}
    1.97 +
    1.98 +EXPORT_C TInt SetPls(TAny* aPls, const TUid& aLibraryUid)   		 
    1.99 +	{
   1.100 +	TProcessId procId = RProcess().Id();
   1.101 +	TInt slot = -1;
   1.102 +
   1.103 +	if (LastUsedProcessSlot >= 0)
   1.104 +		{		
   1.105 +		for (TInt i = 0; i <= LastUsedProcessSlot; ++i)
   1.106 +			{
   1.107 +			if (!WsdArray[i].iPid.Id())
   1.108 +				{
   1.109 +				if (slot == -1)
   1.110 +					{
   1.111 +					 slot = i;
   1.112 +					}
   1.113 +					
   1.114 +				continue;
   1.115 +				}
   1.116 +			else if (WsdArray[i].iPid == procId)	
   1.117 +				{
   1.118 +					// We are about to set the Pls of a new library for this process
   1.119 +					TInt firstUnused = WsdArray[i].iFirstUnusedSlot;
   1.120 +					if (KMaxNumberOfLibraries == firstUnused)
   1.121 +						{
   1.122 +						// The library array is full for this process
   1.123 +						return KErrNoMemory;
   1.124 +						}
   1.125 +					else
   1.126 +						{
   1.127 +						// Store the PLS for the specified library
   1.128 +						StorePls(i, firstUnused, aPls, aLibraryUid);
   1.129 +						return KErrNone;
   1.130 +						}
   1.131 +				}
   1.132 +			}
   1.133 +		
   1.134 +		// The remainder of WsdArray is not used, so the process is
   1.135 +		// not in it. If an empty slot hasn't yet been found then...			
   1.136 +		if (slot == -1)
   1.137 +			{
   1.138 +			// ...  use the next unused slot in the array, if there is one
   1.139 +			if (LastUsedProcessSlot < (KMaxNumberOfProcesses - 1))
   1.140 +				{
   1.141 +				slot = LastUsedProcessSlot + 1;
   1.142 +				}
   1.143 +			else
   1.144 +				{
   1.145 +				// ... the array is full (there are no empty slots). 
   1.146 +				// Perform a clean up of the array to free any process slots that
   1.147 +				// belong to dead processes to see if there is a slot that we can reuse
   1.148 +				TInt slotToReuse = CleanupDeadProcessSlots();
   1.149 +				if (slotToReuse == -1)
   1.150 +					{
   1.151 +					// There are no reusable slots in the process array
   1.152 +					return KErrNoMemory;
   1.153 +					}
   1.154 +				slot = slotToReuse;
   1.155 +				}
   1.156 +			}
   1.157 +		}
   1.158 +	else
   1.159 +		{
   1.160 +		slot = 0;
   1.161 +		}
   1.162 +	
   1.163 +	// Store the PLS for the specified library	
   1.164 +	StorePls(slot, 0, aPls, aLibraryUid);
   1.165 +	
   1.166 +	// Store the process details too as this process is new to WsdArray
   1.167 +	WsdArray[slot].iPid = procId;
   1.168 +	
   1.169 +	// Update the LastUsedProcessSlot if necessary		    
   1.170 +	if (slot > LastUsedProcessSlot)
   1.171 +		{
   1.172 +		 LastUsedProcessSlot = slot;
   1.173 +		}
   1.174 +	
   1.175 +	return KErrNone;
   1.176 +	}
   1.177 +	
   1.178 +EXPORT_C TAny* AllocatePls(const TInt& aSize)
   1.179 +	{
   1.180 +	return VirtualAlloc(NULL, 
   1.181 +						aSize,
   1.182 +						MEM_COMMIT | MEM_RESERVE,
   1.183 +						PAGE_READWRITE);
   1.184 +	}
   1.185 +
   1.186 +EXPORT_C TInt FreePls(TAny* aPls)
   1.187 +	{
   1.188 +	if (!VirtualFree(aPls, 0, MEM_RELEASE))
   1.189 +		{
   1.190 +		return KErrAccessDenied;
   1.191 +		}
   1.192 +	aPls = NULL;
   1.193 +	return KErrNone;
   1.194 +	}
   1.195 +
   1.196 +EXPORT_C TAny* ObtainPlsMutex()
   1.197 +	{
   1.198 +	// Get a handle to the mutex (the mutex will be created 
   1.199 +	// if it doesn't already exist) and then wait to acquire 
   1.200 +	// ownership of the mutex
   1.201 +	HANDLE mutexHandle = CreateMutex(NULL, FALSE, KMutexName);
   1.202 +	if ((!mutexHandle) || (WaitForSingleObject(mutexHandle, INFINITE) == WAIT_FAILED)) 
   1.203 +		{
   1.204 +		User::Panic(KMutexGetFailure, KErrAccessDenied);
   1.205 +		}
   1.206 +		
   1.207 +	return mutexHandle;
   1.208 +	}
   1.209 +	
   1.210 +EXPORT_C void ReleasePlsMutex(TAny* aMutexHandle)
   1.211 +	{
   1.212 +	if (!ReleaseMutex(aMutexHandle))
   1.213 +		{
   1.214 +		 User::Panic(KMutexReleaseFailure, KErrAccessDenied);
   1.215 +		}
   1.216 +	}
   1.217 +	
   1.218 +// LOCAL FUNCTIONS DEFINITIONS
   1.219 +
   1.220 +/**  
   1.221 +Iterates through the WSD array and frees each slot that belongs to a dead process
   1.222 +(the stored data is reset and all associated PLS memory is freed).
   1.223 +Returns the index of the first freed slot if at least one slot was freed,
   1.224 +otherwise -1
   1.225 +*/
   1.226 +LOCAL_C TInt CleanupDeadProcessSlots()
   1.227 +	{
   1.228 +	TInt firstReusableSlot = -1;
   1.229 +	TUid nullUid = TUid::Null();
   1.230 +	LastUsedProcessSlot = -1;
   1.231 +	RProcess proc;
   1.232 +	for (TInt i = 0; i < KMaxNumberOfProcesses; ++i)
   1.233 +		{
   1.234 +		if(proc.Open(WsdArray[i].iPid) == KErrNone)
   1.235 +			{
   1.236 +			if(proc.ExitType()==EExitPending)
   1.237 +				{
   1.238 +				LastUsedProcessSlot = i;
   1.239 +				proc.Close();
   1.240 +				continue;	
   1.241 +				}
   1.242 +			else
   1.243 +				proc.Close();
   1.244 +			
   1.245 +			}
   1.246 +		
   1.247 +		// Process with the given name does not exist in
   1.248 +		// the system, so the slot could be reused
   1.249 +		WsdArray[i].iPid = 0;
   1.250 +		
   1.251 +
   1.252 +		// Free all of the PLS memory associated with this process
   1.253 +		TInt firstUnused = WsdArray[i].iFirstUnusedSlot;
   1.254 +		WsdArray[i].iFirstUnusedSlot = 0;
   1.255 +		for (TInt j = 0; j < firstUnused; ++j)
   1.256 +			{
   1.257 +			FreePls(WsdArray[i].iDllData[j].iPtr);
   1.258 +			WsdArray[i].iDllData[j].iLibraryUid = nullUid;
   1.259 +			}
   1.260 +
   1.261 +		if (firstReusableSlot == -1)
   1.262 +			{
   1.263 +			// Set the slot to reuse
   1.264 +			firstReusableSlot = i;
   1.265 +			}
   1.266 +		}
   1.267 +		
   1.268 +	return firstReusableSlot;
   1.269 +}	
   1.270 +
   1.271 +/**  
   1.272 +Stores the specified PLS object and library TUid at the specified location in the WSD array.
   1.273 +Takes as parameters the process slot to use in the WSD array, the slot to use in the library 
   1.274 +array associated with the given process, the PLS object to be stored and the TUid of the 
   1.275 +library DLL that the PLS object belongs to
   1.276 +*/
   1.277 +LOCAL_C void StorePls(const TInt& aProcessSlot, const TInt& aLibrarySlot, TAny* aPls, const TUid& aLibraryUid)
   1.278 +	{
   1.279 +	 WsdArray[aProcessSlot].iDllData[aLibrarySlot].iPtr = aPls;
   1.280 +	 WsdArray[aProcessSlot].iDllData[aLibrarySlot].iLibraryUid = aLibraryUid;
   1.281 +	 ++WsdArray[aProcessSlot].iFirstUnusedSlot;	
   1.282 +	}
   1.283 +
   1.284 +#endif // __WINSCW__