os/ossrv/genericopenlibs/openenvcore/ewsd/src/ewsd.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // Name        : ewsd.cpp
    15 // Part of     : ewsd library
    16 // Contains the definitions of the APIs of the emulator WSD library 
    17 //
    18 
    19 
    20 
    21 #ifdef __WINSCW__
    22 
    23 #include <e32std.h>
    24 #include <windows.h>
    25 
    26 // Constant declarations
    27 const TInt KMaxNumberOfProcesses = 100;
    28 const TInt KMaxNumberOfLibraries = 50;
    29 
    30 // Panic strings
    31 _LIT(KMutexGetFailure, "WSD mutex get failed");
    32 _LIT(KMutexReleaseFailure, "WSD mutex release failed");
    33 
    34 // Mutex name
    35 unsigned short KMutexName[] = 
    36 	{
    37 		'E', 'W', 'S', 'D', 'M', 'u', 't', 'e', 'x'
    38 	};
    39 
    40 // LOCAL STRUCTURE DECLARATIONS
    41 
    42 // Data structure to store the WSD info associated with a particular DLL
    43 struct TDllData
    44 	{
    45 	TUid  iLibraryUid;
    46 	TAny* iPtr;
    47 	};
    48 
    49 // Data structure to store the DLL information associated with a process
    50 struct TWsdNode
    51 	{
    52 	TProcessId  iPid;
    53 	TInt  		iFirstUnusedSlot;
    54 	struct TDllData iDllData[KMaxNumberOfLibraries];
    55 	};
    56 	
    57 // WSD array variables
    58 struct TWsdNode WsdArray[KMaxNumberOfProcesses];
    59 TInt LastUsedProcessSlot = -1;
    60 
    61 // LOCAL FUNCTION DECLARATIONS
    62 
    63 LOCAL_C TInt CleanupDeadProcessSlots();
    64 LOCAL_C void StorePls(const TInt& aProcessSlot, const TInt& aLibrarySlot, TAny* aPls, const TUid& aLibraryUid);  
    65 	
    66 // EXPORTED FUNCTION DEFINITIONS
    67 
    68 EXPORT_C TAny* CheckPls(const TUid& aLibraryUid)
    69 	{
    70 	TProcessId procId = RProcess().Id();
    71 	
    72 	for (TInt i = 0; i <= LastUsedProcessSlot; ++i)
    73 		{
    74 		if (WsdArray[i].iPid == procId)
    75 			{
    76 			// This process has a slot in the WsdArray - now check
    77 			// whether its DLL array contains the specified library
    78 			TInt firstUnused = WsdArray[i].iFirstUnusedSlot;
    79 			for (TInt j = 0; j < firstUnused; ++j)	
    80 				{
    81 				if (aLibraryUid == WsdArray[i].iDllData[j].iLibraryUid)
    82 					{
    83 					// The specified library is present so return the PLS object
    84 					return WsdArray[i].iDllData[j].iPtr;
    85 					}
    86 				}
    87 			break;
    88 			}
    89 		}
    90 	
    91 	// The PLS object hasn't yet been stored	
    92 	return NULL;
    93 	}
    94 
    95 EXPORT_C TInt SetPls(TAny* aPls, const TUid& aLibraryUid)   		 
    96 	{
    97 	TProcessId procId = RProcess().Id();
    98 	TInt slot = -1;
    99 
   100 	if (LastUsedProcessSlot >= 0)
   101 		{		
   102 		for (TInt i = 0; i <= LastUsedProcessSlot; ++i)
   103 			{
   104 			if (!WsdArray[i].iPid.Id())
   105 				{
   106 				if (slot == -1)
   107 					{
   108 					 slot = i;
   109 					}
   110 					
   111 				continue;
   112 				}
   113 			else if (WsdArray[i].iPid == procId)	
   114 				{
   115 					// We are about to set the Pls of a new library for this process
   116 					TInt firstUnused = WsdArray[i].iFirstUnusedSlot;
   117 					if (KMaxNumberOfLibraries == firstUnused)
   118 						{
   119 						// The library array is full for this process
   120 						return KErrNoMemory;
   121 						}
   122 					else
   123 						{
   124 						// Store the PLS for the specified library
   125 						StorePls(i, firstUnused, aPls, aLibraryUid);
   126 						return KErrNone;
   127 						}
   128 				}
   129 			}
   130 		
   131 		// The remainder of WsdArray is not used, so the process is
   132 		// not in it. If an empty slot hasn't yet been found then...			
   133 		if (slot == -1)
   134 			{
   135 			// ...  use the next unused slot in the array, if there is one
   136 			if (LastUsedProcessSlot < (KMaxNumberOfProcesses - 1))
   137 				{
   138 				slot = LastUsedProcessSlot + 1;
   139 				}
   140 			else
   141 				{
   142 				// ... the array is full (there are no empty slots). 
   143 				// Perform a clean up of the array to free any process slots that
   144 				// belong to dead processes to see if there is a slot that we can reuse
   145 				TInt slotToReuse = CleanupDeadProcessSlots();
   146 				if (slotToReuse == -1)
   147 					{
   148 					// There are no reusable slots in the process array
   149 					return KErrNoMemory;
   150 					}
   151 				slot = slotToReuse;
   152 				}
   153 			}
   154 		}
   155 	else
   156 		{
   157 		slot = 0;
   158 		}
   159 	
   160 	// Store the PLS for the specified library	
   161 	StorePls(slot, 0, aPls, aLibraryUid);
   162 	
   163 	// Store the process details too as this process is new to WsdArray
   164 	WsdArray[slot].iPid = procId;
   165 	
   166 	// Update the LastUsedProcessSlot if necessary		    
   167 	if (slot > LastUsedProcessSlot)
   168 		{
   169 		 LastUsedProcessSlot = slot;
   170 		}
   171 	
   172 	return KErrNone;
   173 	}
   174 	
   175 EXPORT_C TAny* AllocatePls(const TInt& aSize)
   176 	{
   177 	return VirtualAlloc(NULL, 
   178 						aSize,
   179 						MEM_COMMIT | MEM_RESERVE,
   180 						PAGE_READWRITE);
   181 	}
   182 
   183 EXPORT_C TInt FreePls(TAny* aPls)
   184 	{
   185 	if (!VirtualFree(aPls, 0, MEM_RELEASE))
   186 		{
   187 		return KErrAccessDenied;
   188 		}
   189 	aPls = NULL;
   190 	return KErrNone;
   191 	}
   192 
   193 EXPORT_C TAny* ObtainPlsMutex()
   194 	{
   195 	// Get a handle to the mutex (the mutex will be created 
   196 	// if it doesn't already exist) and then wait to acquire 
   197 	// ownership of the mutex
   198 	HANDLE mutexHandle = CreateMutex(NULL, FALSE, KMutexName);
   199 	if ((!mutexHandle) || (WaitForSingleObject(mutexHandle, INFINITE) == WAIT_FAILED)) 
   200 		{
   201 		User::Panic(KMutexGetFailure, KErrAccessDenied);
   202 		}
   203 		
   204 	return mutexHandle;
   205 	}
   206 	
   207 EXPORT_C void ReleasePlsMutex(TAny* aMutexHandle)
   208 	{
   209 	if (!ReleaseMutex(aMutexHandle))
   210 		{
   211 		 User::Panic(KMutexReleaseFailure, KErrAccessDenied);
   212 		}
   213 	}
   214 	
   215 // LOCAL FUNCTIONS DEFINITIONS
   216 
   217 /**  
   218 Iterates through the WSD array and frees each slot that belongs to a dead process
   219 (the stored data is reset and all associated PLS memory is freed).
   220 Returns the index of the first freed slot if at least one slot was freed,
   221 otherwise -1
   222 */
   223 LOCAL_C TInt CleanupDeadProcessSlots()
   224 	{
   225 	TInt firstReusableSlot = -1;
   226 	TUid nullUid = TUid::Null();
   227 	LastUsedProcessSlot = -1;
   228 	RProcess proc;
   229 	for (TInt i = 0; i < KMaxNumberOfProcesses; ++i)
   230 		{
   231 		if(proc.Open(WsdArray[i].iPid) == KErrNone)
   232 			{
   233 			if(proc.ExitType()==EExitPending)
   234 				{
   235 				LastUsedProcessSlot = i;
   236 				proc.Close();
   237 				continue;	
   238 				}
   239 			else
   240 				proc.Close();
   241 			
   242 			}
   243 		
   244 		// Process with the given name does not exist in
   245 		// the system, so the slot could be reused
   246 		WsdArray[i].iPid = 0;
   247 		
   248 
   249 		// Free all of the PLS memory associated with this process
   250 		TInt firstUnused = WsdArray[i].iFirstUnusedSlot;
   251 		WsdArray[i].iFirstUnusedSlot = 0;
   252 		for (TInt j = 0; j < firstUnused; ++j)
   253 			{
   254 			FreePls(WsdArray[i].iDllData[j].iPtr);
   255 			WsdArray[i].iDllData[j].iLibraryUid = nullUid;
   256 			}
   257 
   258 		if (firstReusableSlot == -1)
   259 			{
   260 			// Set the slot to reuse
   261 			firstReusableSlot = i;
   262 			}
   263 		}
   264 		
   265 	return firstReusableSlot;
   266 }	
   267 
   268 /**  
   269 Stores the specified PLS object and library TUid at the specified location in the WSD array.
   270 Takes as parameters the process slot to use in the WSD array, the slot to use in the library 
   271 array associated with the given process, the PLS object to be stored and the TUid of the 
   272 library DLL that the PLS object belongs to
   273 */
   274 LOCAL_C void StorePls(const TInt& aProcessSlot, const TInt& aLibrarySlot, TAny* aPls, const TUid& aLibraryUid)
   275 	{
   276 	 WsdArray[aProcessSlot].iDllData[aLibrarySlot].iPtr = aPls;
   277 	 WsdArray[aProcessSlot].iDllData[aLibrarySlot].iLibraryUid = aLibraryUid;
   278 	 ++WsdArray[aProcessSlot].iFirstUnusedSlot;	
   279 	}
   280 
   281 #endif // __WINSCW__