genericopenlibs/openenvcore/ewsd/src/ewsd.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     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__