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__