00001 /* 00002 * ============================================================================ 00003 * Name : pls.h 00004 * Part of : Client API for ewsd library 00005 * Description : Contains the client API for using the emulator WSD library 00006 * 00007 * Portions Copyright (c) Symbian Software Ltd 2006. All rights reserved. 00008 * Copyright (C) 2006 Nokia Corporation. 00009 * This material, including documentation and any related 00010 * computer programs, is protected by copyright controlled by 00011 * Nokia Corporation. All rights are reserved. Copying, 00012 * including reproducing, storing, adapting or translating, any 00013 * or all of this material requires the prior written consent of 00014 * Nokia Corporation. This material also contains confidential 00015 * information which may not be disclosed to others without the 00016 * prior written consent of Nokia Corporation. 00017 * ============================================================================ 00018 */ 00019 00020 #ifndef __PLS_H__ 00021 #define __PLS_H__ 00022 00023 #ifdef __WINSCW__ 00024 00025 #include "ewsd.h" 00026 00027 // Panic strings 00028 _LIT(KVirtualAllocFailure, "WSD VirtualAlloc() failed"); 00029 _LIT(KPLSInitFailed, "WSD PLS init failed"); 00030 _LIT(KWsdArrayFull, "WSD process or lib array full"); 00031 00052 template <typename T> 00053 T* Pls(const TUid& aLibraryUid, TInt (*aInitFunc)(T*) = 0) 00054 { 00055 // Fetch the PLS, if it has been set 00056 T* p = (T*) CheckPls(aLibraryUid); 00057 if (p) 00058 { 00059 return p; 00060 } 00061 00062 // Obtain ownership of the mutex 00063 TAny* mutexHandle = ObtainPlsMutex(); 00064 00065 // Check we haven't obtained the mutex from 00066 // another thread that has just set the same PLS! 00067 p = (T*) CheckPls(aLibraryUid); 00068 if (p) 00069 { 00070 ReleasePlsMutex(mutexHandle); 00071 return p; 00072 } 00073 00074 // Allocate the memory for the PLS object 00075 p = (T*) AllocatePls(sizeof(T)); 00076 if (!p) 00077 { 00078 ReleasePlsMutex(mutexHandle); 00079 User::Panic(KVirtualAllocFailure, KErrNoMemory); 00080 } 00081 00082 // Do a placement new to construct the PLS object in the allocated memory 00083 p = new (p) T; 00084 00085 // Call the initialisation function (if one is provided) 00086 // to complete initialisation of the PLS object 00087 if (aInitFunc) 00088 { 00089 if (((*aInitFunc)(p)) != KErrNone) 00090 { 00091 FreePls(p); 00092 ReleasePlsMutex(mutexHandle); 00093 User::Panic(KPLSInitFailed, KErrGeneral); 00094 } 00095 } 00096 00097 // Finally, call SetPls() to store the PLS object. 00098 // NOTE: This step is last to ensure that a PLS object returned by 00099 // CheckPls() is completely constructed/initialised. This is important 00100 // to handle the scenario in which the thread that is creating the PLS 00101 // object is interrupted by another call to Pls() by another thread 00102 if (SetPls(p, aLibraryUid) != KErrNone) 00103 { 00104 // SetPls() failed due to a size limit being reached in the wsdArray 00105 FreePls(p); 00106 ReleasePlsMutex(mutexHandle); 00107 User::Panic(KWsdArrayFull, KErrNoMemory); 00108 } 00109 00110 ReleasePlsMutex(mutexHandle); 00111 return p; 00112 } 00113 00114 // __WINSCW__ 00115 #endif 00116 00117 // __PLS_H__ 00118 #endif 00119