First public contribution.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
15 // Part of : ewsd library
16 // Contains the definitions of the APIs of the emulator WSD library
26 // Constant declarations
27 const TInt KMaxNumberOfProcesses = 100;
28 const TInt KMaxNumberOfLibraries = 50;
31 _LIT(KMutexGetFailure, "WSD mutex get failed");
32 _LIT(KMutexReleaseFailure, "WSD mutex release failed");
35 unsigned short KMutexName[] =
37 'E', 'W', 'S', 'D', 'M', 'u', 't', 'e', 'x'
40 // LOCAL STRUCTURE DECLARATIONS
42 // Data structure to store the WSD info associated with a particular DLL
49 // Data structure to store the DLL information associated with a process
53 TInt iFirstUnusedSlot;
54 struct TDllData iDllData[KMaxNumberOfLibraries];
57 // WSD array variables
58 struct TWsdNode WsdArray[KMaxNumberOfProcesses];
59 TInt LastUsedProcessSlot = -1;
61 // LOCAL FUNCTION DECLARATIONS
63 LOCAL_C TInt CleanupDeadProcessSlots();
64 LOCAL_C void StorePls(const TInt& aProcessSlot, const TInt& aLibrarySlot, TAny* aPls, const TUid& aLibraryUid);
66 // EXPORTED FUNCTION DEFINITIONS
68 EXPORT_C TAny* CheckPls(const TUid& aLibraryUid)
70 TProcessId procId = RProcess().Id();
72 for (TInt i = 0; i <= LastUsedProcessSlot; ++i)
74 if (WsdArray[i].iPid == procId)
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)
81 if (aLibraryUid == WsdArray[i].iDllData[j].iLibraryUid)
83 // The specified library is present so return the PLS object
84 return WsdArray[i].iDllData[j].iPtr;
91 // The PLS object hasn't yet been stored
95 EXPORT_C TInt SetPls(TAny* aPls, const TUid& aLibraryUid)
97 TProcessId procId = RProcess().Id();
100 if (LastUsedProcessSlot >= 0)
102 for (TInt i = 0; i <= LastUsedProcessSlot; ++i)
104 if (!WsdArray[i].iPid.Id())
113 else if (WsdArray[i].iPid == procId)
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)
119 // The library array is full for this process
124 // Store the PLS for the specified library
125 StorePls(i, firstUnused, aPls, aLibraryUid);
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...
135 // ... use the next unused slot in the array, if there is one
136 if (LastUsedProcessSlot < (KMaxNumberOfProcesses - 1))
138 slot = LastUsedProcessSlot + 1;
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)
148 // There are no reusable slots in the process array
160 // Store the PLS for the specified library
161 StorePls(slot, 0, aPls, aLibraryUid);
163 // Store the process details too as this process is new to WsdArray
164 WsdArray[slot].iPid = procId;
166 // Update the LastUsedProcessSlot if necessary
167 if (slot > LastUsedProcessSlot)
169 LastUsedProcessSlot = slot;
175 EXPORT_C TAny* AllocatePls(const TInt& aSize)
177 return VirtualAlloc(NULL,
179 MEM_COMMIT | MEM_RESERVE,
183 EXPORT_C TInt FreePls(TAny* aPls)
185 if (!VirtualFree(aPls, 0, MEM_RELEASE))
187 return KErrAccessDenied;
193 EXPORT_C TAny* ObtainPlsMutex()
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))
201 User::Panic(KMutexGetFailure, KErrAccessDenied);
207 EXPORT_C void ReleasePlsMutex(TAny* aMutexHandle)
209 if (!ReleaseMutex(aMutexHandle))
211 User::Panic(KMutexReleaseFailure, KErrAccessDenied);
215 // LOCAL FUNCTIONS DEFINITIONS
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,
223 LOCAL_C TInt CleanupDeadProcessSlots()
225 TInt firstReusableSlot = -1;
226 TUid nullUid = TUid::Null();
227 LastUsedProcessSlot = -1;
229 for (TInt i = 0; i < KMaxNumberOfProcesses; ++i)
231 if(proc.Open(WsdArray[i].iPid) == KErrNone)
233 if(proc.ExitType()==EExitPending)
235 LastUsedProcessSlot = i;
244 // Process with the given name does not exist in
245 // the system, so the slot could be reused
246 WsdArray[i].iPid = 0;
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)
254 FreePls(WsdArray[i].iDllData[j].iPtr);
255 WsdArray[i].iDllData[j].iLibraryUid = nullUid;
258 if (firstReusableSlot == -1)
260 // Set the slot to reuse
261 firstReusableSlot = i;
265 return firstReusableSlot;
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
274 LOCAL_C void StorePls(const TInt& aProcessSlot, const TInt& aLibrarySlot, TAny* aPls, const TUid& aLibraryUid)
276 WsdArray[aProcessSlot].iDllData[aLibrarySlot].iPtr = aPls;
277 WsdArray[aProcessSlot].iDllData[aLibrarySlot].iLibraryUid = aLibraryUid;
278 ++WsdArray[aProcessSlot].iFirstUnusedSlot;