graphicscomposition/surfaceupdate/src/surfaceupdateserver.cpp
changeset 98 bf7481649c98
parent 0 5d03bc08d59c
child 110 7f25ef56562d
--- a/graphicscomposition/surfaceupdate/src/surfaceupdateserver.cpp	Thu May 27 14:13:51 2010 +0300
+++ b/graphicscomposition/surfaceupdate/src/surfaceupdateserver.cpp	Fri Jun 11 14:58:47 2010 +0300
@@ -23,11 +23,13 @@
 #ifdef TEST_SURFACE_UPDATE
 #include "surfaceupdatetest.h"
 #endif
-
+#include <e32atomics.h>
 
 
 const TUint KDefaultHeapSize=0x10000;
 
+void *gProvider = NULL;
+RFastLock gProviderFastLock;
 
 /**
 The server maintains session with the clients. 
@@ -351,12 +353,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 +371,6 @@
 			}
 		}
 	
-	CSurfaceUpdateServer* server = (CSurfaceUpdateServer*) Server();
 	notifier = new (ELeave) CUpdateReceiverNotificationBatch(this, server->NumUpdateReceivers());
 	CleanupStack::PushL(notifier);
 	iUpdateReceiverNotificationBatches.AppendL(notifier);
@@ -883,6 +886,11 @@
 	}
 #endif
 
+void CUpdateReceiverNotificationBatch::SetNumUpdateReceivers(TInt aNumUpdateReceivers)
+    {
+    __ASSERT_DEBUG(iType == EUpdateSrvReusable, CSurfaceUpdateServer::PanicServer(EUpdateServPanicDataIntegrity));
+    iNumUpdateReceivers = aNumUpdateReceivers;
+    }
 /**
 
 The class will be used by composition receiver
@@ -955,6 +963,10 @@
 
 	if(thread.Open(iThreadId) == KErrNone)
 		{
+	    TInt err = gProviderFastLock.CreateLocal();
+		//ignore error on double create.
+	    gProviderFastLock.Wait();
+	    gProvider = NULL;
 		if (iServer)
 			{
 			while((static_cast<CSurfaceUpdateServer*> (iServer))-> iNumberPendingNotification)
@@ -969,7 +981,7 @@
 		User::WaitForRequest(status1);
 		thread.Close();
 		
-		Dll::SetTls(NULL);
+     	gProviderFastLock.Close();
 		}
 #endif
 	}
@@ -1034,10 +1046,21 @@
 #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 +1077,7 @@
 		TRAP(res, tm.FormatL(buf, _L("_%H%T%S%C")));
 		if(res != KErrNone)	
 			{
+			gProviderFastLock.Signal();
 			return res;
 			}
 		TBuf<128> threadName(serverName);
@@ -1077,7 +1101,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 +1109,6 @@
 			serverThread.Close();
 			}
 		}
+       gProviderFastLock.Signal();
 		return res;
 	}