testexecfw/tef/utils/inc/tefshareddata.inl
changeset 0 3e07fef1e154
equal deleted inserted replaced
-1:000000000000 0:3e07fef1e154
       
     1 /*
       
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 * Template class implementation for creating RChunk object with memory for sharing data
       
    16 * Construction of template object for sharing data requires
       
    17 * Name for RChunk memory, size of data and null pointer of the object type to be shared
       
    18 * Construction of template class for accessing the shared data requires
       
    19 * Name for RChunk memory and null pointer of the object type already shared
       
    20 *
       
    21 */
       
    22 
       
    23 
       
    24 
       
    25 /**
       
    26  @file TEFSharedData.inl
       
    27  @prototype
       
    28  @test
       
    29 */
       
    30 
       
    31 template <class T>
       
    32 inline CTEFSharedData<T>::CTEFSharedData()
       
    33 /**
       
    34  * Constructor
       
    35  */
       
    36 	: iPtr(NULL)
       
    37 	{
       
    38 	// Intialising member data
       
    39 	iSharedChunkName.Zero();
       
    40 	iSharedMutexName.Zero();
       
    41 	}
       
    42 
       
    43 template <class T>
       
    44 inline CTEFSharedData<T>* CTEFSharedData<T>::NewL(T*& aPtr, const TInt aLength, const TDesC& aName)
       
    45 /**
       
    46  * Updates the null pointer with address of RChunk base for user to copy data
       
    47  * Two phase construction
       
    48  *
       
    49  * @param	aPtr - Address of null pointer to object that needs to be shared as a global chunk
       
    50  * @param	aLength - Size to be allocated in RChunk base for the object to be shared
       
    51  * @param	aName - Descriptor containing the name to be assigned to the global chunk
       
    52  *
       
    53  * @leave	system wide error
       
    54  *
       
    55  * @return	Instance of the TEFSharedData template class object
       
    56  */
       
    57 	{
       
    58 	CTEFSharedData<T>* self=CTEFSharedData<T>::NewLC(aPtr,aLength,aName);
       
    59 	CleanupStack::Pop();
       
    60 	return self;
       
    61 	}
       
    62 
       
    63 template <class T>
       
    64 inline CTEFSharedData<T>* CTEFSharedData<T>::NewL(T*& aPtr, const TDesC& aName)
       
    65 /**
       
    66  * Updates the null pointer with address of RChunk base for user to update data
       
    67  * Two phase construction
       
    68  *
       
    69  * @param	aPtr - Address of null pointer to object that is shared in a global chunk
       
    70  * @param	aName - Descriptor containing the name assigned to the global chunk
       
    71  *
       
    72  * @leave	system wide error
       
    73  *
       
    74  * @return	Instance of the TEFSharedData template class object
       
    75  */
       
    76 	{
       
    77 	CTEFSharedData<T>* self=CTEFSharedData<T>::NewLC(aPtr,aName);
       
    78 	CleanupStack::Pop();
       
    79 	return self;
       
    80 	}
       
    81 
       
    82 template <class T>
       
    83 inline CTEFSharedData<T>* CTEFSharedData<T>::NewLC(T*& aPtr, const TInt aLength, const TDesC& aName)
       
    84 /**
       
    85  * Updates the null pointer with address of RChunk base for user to copy data
       
    86  * Two phase construction
       
    87  *
       
    88  * @param	aPtr - Address of null pointer to object that needs to be shared as a global chunk
       
    89  * @param	aLength - Size to be allocated in RChunk base for the object to be shared
       
    90  * @param	aName - Descriptor containing the name to be assigned to the global chunk
       
    91  *
       
    92  * @leave	system wide error
       
    93  *
       
    94  * @return	Instance of the TEFSharedData template class object and pushes to CleanupStack
       
    95  */
       
    96 	{
       
    97 	CTEFSharedData<T>* self=new (ELeave) CTEFSharedData<T>();
       
    98 	CleanupStack::PushL(self);
       
    99 	self->ConstructL(aPtr,aLength,aName);
       
   100 	return self;
       
   101 	}
       
   102 
       
   103 template <class T>
       
   104 inline CTEFSharedData<T>* CTEFSharedData<T>::NewLC(T*& aPtr, const TDesC& aName)
       
   105 /**
       
   106  * Updates the null pointer with address of RChunk base for user to update data
       
   107  * Two phase construction
       
   108  *
       
   109  * @param	aPtr - Address of null pointer to object that is shared in a global chunk
       
   110  * @param	aName - Descriptor containing the name assigned to the global chunk
       
   111  *
       
   112  * @leave	system wide error
       
   113  *
       
   114  * @return	Instance of the TEFSharedData template class object and pushes to CleanupStack
       
   115  */
       
   116 	{
       
   117 	CTEFSharedData<T>* self=new (ELeave) CTEFSharedData<T>();
       
   118 	CleanupStack::PushL(self);
       
   119 	self->ConstructL( aPtr, aName );
       
   120 	return self;
       
   121 	}
       
   122 
       
   123 template <class T>
       
   124 inline void CTEFSharedData<T>::ConstructL(T*& aPtr, const TInt aLength, const TDesC& aName)
       
   125 /**
       
   126  * Opens up a handle and retrieves base address of the created chunk memory to iPtr
       
   127  * Updates the null pointer with address of RChunk base for user to copy data
       
   128  *
       
   129  * @param	aPtr - Address of null pointer to object that needs to be shared in a global chunk
       
   130  * @param	aLength - Size to be allocated in RChunk base for the object to be shared
       
   131  * @param	aName - Descriptor containing the name to be assigned to the global chunk
       
   132  *
       
   133  * @leave	system wide error
       
   134  */
       
   135 	{
       
   136 	iSharedChunkName.Zero();
       
   137 	iSharedChunkName.Copy(_L("TEF"));
       
   138 	iSharedChunkName.Append(aName);
       
   139 
       
   140 	iSharedMutexName.Zero();
       
   141 	iSharedMutexName.Copy(_L("TEFMutex"));
       
   142 	iSharedMutexName.Append(aName);
       
   143 
       
   144 	TInt error = KErrNone;
       
   145 	error = iSharedDataChunk.CreateGlobal(iSharedChunkName, aLength, aLength + 1);
       
   146 	if( error == KErrAlreadyExists )
       
   147 		{
       
   148 		// Chunk memory already created by another process
       
   149 		// Open a handle to already created global chunk
       
   150 		error = iSharedDataChunk.OpenGlobal(iSharedChunkName,EFalse);
       
   151 		if( error != KErrNone )
       
   152 			{
       
   153 			User::Leave(error);
       
   154 			}
       
   155 		// Open a mutex handle to existing global chunk
       
   156 		error = iMutex.OpenGlobal(iSharedMutexName);
       
   157 		if( error != KErrNone )
       
   158 			{
       
   159 			User::Leave(error);
       
   160 			}
       
   161 
       
   162 		// If we have looked up a shared RChunk we will need to update it
       
   163 		//  with the object passed into the constructor
       
   164 		T* baseAddress = (T*)iSharedDataChunk.Base();
       
   165 		iPtr = baseAddress;
       
   166 		aPtr = iPtr;
       
   167 		}
       
   168 	else if( error == KErrNone )
       
   169 		{
       
   170 		// Global chunk created by current process
       
   171 		// Copy the object to be shared to Chunks base address
       
   172 		T* baseAddress = (T*)iSharedDataChunk.Base();
       
   173 		iPtr = baseAddress;
       
   174 		aPtr = iPtr;
       
   175 		// Create a mutex object for the newly created global chunk
       
   176 		error = iMutex.CreateGlobal(iSharedMutexName);
       
   177 		if( error != KErrNone )
       
   178 			{
       
   179 			User::Leave(error);
       
   180 			}
       
   181 		}
       
   182 	else
       
   183 		{
       
   184 		User::Leave(error);
       
   185 		}
       
   186     }
       
   187 
       
   188 template <class T>
       
   189 inline void CTEFSharedData<T>::ConstructL(T*& aPtr, const TDesC& aName)
       
   190 /**
       
   191  * Opens up a handle and retrieves base address of the created chunk memory to iPtr
       
   192  * Updates the null pointer with address of RChunk base for user to update data
       
   193  *
       
   194  * @param	aPtr - Address of null pointer to object type shared in a global chunk
       
   195  * @param	aName - Descriptor containing the name assigned to the global chunk
       
   196  *
       
   197  * @leave	system wide error
       
   198  */
       
   199 	{
       
   200 	SetNameL( aName );
       
   201 	aPtr = Ptr();
       
   202     }
       
   203 
       
   204 
       
   205 template <class T>
       
   206 inline T* CTEFSharedData<T>::Ptr()
       
   207 /**
       
   208  * @return - Pointer to the base of the RChunk object memory in heap
       
   209  */
       
   210 	{
       
   211 	// Since we are using RChunk::Close() the pointer will always be valid
       
   212 	// The shared RChunk can not have been deleted as it is a reference counting object
       
   213 	return iPtr;
       
   214 	}
       
   215 
       
   216 template <class T>
       
   217 inline void CTEFSharedData<T>::SetNameL( const TDesC& aName )
       
   218 /**
       
   219  * Opens up a handle to the existing chunk & retrieves the base address to iPtr
       
   220  *
       
   221  * @param aName - Name of the global chunk memory for a shared object
       
   222  */
       
   223 	{
       
   224 	// Check to see if we already have a handle to a shared RChunk
       
   225 	if( iPtr != NULL )
       
   226 		{
       
   227 		// Close this before searching for the new one
       
   228 		TInt handle = 0;
       
   229 		handle = iSharedDataChunk.Handle();
       
   230 		if(handle != 0)
       
   231 			{
       
   232 			iPtr = NULL;
       
   233 			iMutex.Close();
       
   234 			iSharedDataChunk.Close();
       
   235 			}
       
   236 		}
       
   237 
       
   238 	// Now search for and open the new shared RChunk
       
   239 	iSharedChunkName.Zero();
       
   240 	iSharedChunkName.Copy(_L("TEF"));
       
   241 	iSharedChunkName.Append(aName);
       
   242 
       
   243 	iSharedMutexName.Zero();
       
   244 	iSharedMutexName.Copy(_L("TEFMutex"));
       
   245 	iSharedMutexName.Append(aName);
       
   246 
       
   247 	TInt error = KErrNone;
       
   248 	// Open a handle to a existing chunk memory
       
   249 	error = iSharedDataChunk.OpenGlobal(iSharedChunkName,EFalse);
       
   250 	if( error == KErrNone )
       
   251 		{
       
   252 		// Open a mutex handle for the chunk memory
       
   253 		error = iMutex.OpenGlobal(iSharedMutexName);
       
   254 		if( error == KErrNone )
       
   255 			{
       
   256 			// Retrieve base address of chunk memory & assign it to iPtr
       
   257 			T* baseAddress = reinterpret_cast<T*>(iSharedDataChunk.Base());
       
   258 			iPtr = baseAddress;
       
   259 			}
       
   260 		}
       
   261 
       
   262 	if( error != KErrNone )
       
   263 		{
       
   264 		User::Leave(error);
       
   265 		}
       
   266 	}
       
   267 
       
   268 template <class T>
       
   269 inline void CTEFSharedData<T>::EnterCriticalSection()
       
   270 /**
       
   271  * Establishes a lock to global chunk access
       
   272  * Makes other proces to wait for a signal
       
   273  */
       
   274 	{
       
   275 	iMutex.Wait();
       
   276 	}
       
   277 
       
   278 template <class T>
       
   279 inline void CTEFSharedData<T>::ExitCriticalSection()
       
   280 /**
       
   281  * Releases the lock to global chunk access
       
   282  * Signals for a process to establish a lock
       
   283  */
       
   284 	{
       
   285 	iMutex.Signal();
       
   286 	}
       
   287 
       
   288 template <class T>
       
   289 inline CTEFSharedData<T>::~CTEFSharedData()
       
   290 /**
       
   291  * Destructor
       
   292  */
       
   293 	{
       
   294 	// Cleanup everything.
       
   295 	TInt handle = 0;
       
   296 	// Checks for an existing handle to the global chunk
       
   297 	// Ensures global objects are not closed already by another process
       
   298 	handle = iMutex.Handle();
       
   299 	if (handle != 0)
       
   300 		{
       
   301 		iMutex.Close();
       
   302 		}
       
   303 
       
   304 	handle = iSharedDataChunk.Handle();
       
   305 	if (handle != 0)
       
   306 		{
       
   307 		iSharedDataChunk.Close();
       
   308 		}
       
   309 	iPtr = NULL;
       
   310 	}