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