--- a/graphicscomposition/surfaceupdate/src/surfaceupdateserver.cpp Wed Jun 16 12:37:57 2010 +0100
+++ b/graphicscomposition/surfaceupdate/src/surfaceupdateserver.cpp Thu Jul 22 16:46:06 2010 +0100
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -25,9 +25,10 @@
#endif
-
const TUint KDefaultHeapSize=0x10000;
+void *gProvider = NULL;
+RFastLock gProviderFastLock;
/**
The server maintains session with the clients.
@@ -351,12 +352,14 @@
{
TInt numElement = iUpdateReceiverNotificationBatches.Count();
CUpdateReceiverNotificationBatch* notifier = NULL;
+ CSurfaceUpdateServer* server = (CSurfaceUpdateServer*) Server();
for(TInt index = 0; index < numElement; index++)
{
notifier = iUpdateReceiverNotificationBatches[index];
if(notifier->iType == EUpdateSrvReusable)
{
__ASSERT_ALWAYS(notifier->iMsg.IsNull(), CSurfaceUpdateServer::PanicServer(EUpdateServPanicDataIntegrity));
+ notifier->SetNumUpdateReceivers(server->NumUpdateReceivers());
if(numElement > index + 1)
{
//to improve a search, append the element to the end of the array
@@ -367,7 +370,6 @@
}
}
- CSurfaceUpdateServer* server = (CSurfaceUpdateServer*) Server();
notifier = new (ELeave) CUpdateReceiverNotificationBatch(this, server->NumUpdateReceivers());
CleanupStack::PushL(notifier);
iUpdateReceiverNotificationBatches.AppendL(notifier);
@@ -883,6 +885,20 @@
}
#endif
+
+/**
+Set number of UpdateReceivers - called when update receivers are added/removed.
+
+@param aNumUpdateReceivers - new number of update receivers for the batch.
+ */
+void CUpdateReceiverNotificationBatch::SetNumUpdateReceivers(TInt aNumUpdateReceivers)
+ {
+ __ASSERT_DEBUG(aNumUpdateReceivers >= 0 && aNumUpdateReceivers < 1000 /* arbitrary "large" limit */,
+ CSurfaceUpdateServer::PanicServer(EUpdateServPanicDataIntegrity));
+ __ASSERT_DEBUG(iType == EUpdateSrvReusable,
+ CSurfaceUpdateServer::PanicServer(EUpdateServPanicDataIntegrity));
+ iNumUpdateReceivers = aNumUpdateReceivers;
+ }
/**
The class will be used by composition receiver
@@ -955,6 +971,11 @@
if(thread.Open(iThreadId) == KErrNone)
{
+ TInt err = gProviderFastLock.CreateLocal();
+ __ASSERT_ALWAYS(err == KErrNone || err == KErrAlreadyExists, CSurfaceUpdateServer::PanicServer(EUpdateServPanicGlobalFastLock));
+
+ gProviderFastLock.Wait();
+ gProvider = NULL;
if (iServer)
{
while((static_cast<CSurfaceUpdateServer*> (iServer))-> iNumberPendingNotification)
@@ -969,7 +990,7 @@
User::WaitForRequest(status1);
thread.Close();
- Dll::SetTls(NULL);
+ gProviderFastLock.Close();
}
#endif
}
@@ -1014,30 +1035,30 @@
thus mustn't delete it. The pointer will be valid until server is operating,
i.e. system is up.
-@panic KErrAccessDenied If is called from process other than WSERV.
@return KErrNone if an operation is successful, any other system error codes otherwise
*/
EXPORT_C TInt StartSurfaceUpdateServer(MSurfaceUpdateServerProvider*& aSurfaceUpdateServerProvider)
{
#ifndef TEST_SURFACE_UPDATE
- RProcess process;
- TUidType uidType = process.Type();
- const TInt32 KWservUid = 268450592;
- const TUid& uid1 = uidType[2];
-
- if(uid1.iUid != KWservUid) //only wserv process can start the server
- {// some malicious client tries to launch the server
- process.Panic(_L("Access denied"), KErrAccessDenied);
- return KErrAccessDenied;
- }
TPtrC serverName(KSurfaceUpdateServerName);
#else
TPtrC serverName(KTestSurfaceUpdateServerName);
#endif
- TAny *provider = Dll::Tls();
+ //locking
+ TInt err = gProviderFastLock.CreateLocal();
+
+ if (err != KErrNone && err != KErrAlreadyExists)
+ {
+ return err;
+ }
+
+ gProviderFastLock.Wait();
+
+ TAny *provider = gProvider;
if(provider)
{
aSurfaceUpdateServerProvider = static_cast <MSurfaceUpdateServerProvider*> (provider);
+ gProviderFastLock.Signal();
return KErrNone;
}
TFullName name;
@@ -1054,6 +1075,7 @@
TRAP(res, tm.FormatL(buf, _L("_%H%T%S%C")));
if(res != KErrNone)
{
+ gProviderFastLock.Signal();
return res;
}
TBuf<128> threadName(serverName);
@@ -1077,7 +1099,7 @@
serverThread.Resume();
User::WaitForRequest(rendezvousStatus);
res = rendezvousStatus.Int();
- Dll::SetTls(aSurfaceUpdateServerProvider);
+ gProvider = aSurfaceUpdateServerProvider;
}
// The thread has not been created - clearly there's been a problem.
else
@@ -1085,5 +1107,6 @@
serverThread.Close();
}
}
+ gProviderFastLock.Signal();
return res;
}