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