graphicscomposition/surfaceupdate/src/surfaceupdateserver.cpp
branchGCC_SURGE
changeset 125 0fecfaa711d2
parent 110 7f25ef56562d
equal deleted inserted replaced
101:8b609b439da2 125:0fecfaa711d2
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
    23 #ifdef TEST_SURFACE_UPDATE
    23 #ifdef TEST_SURFACE_UPDATE
    24 #include "surfaceupdatetest.h"
    24 #include "surfaceupdatetest.h"
    25 #endif
    25 #endif
    26 
    26 
    27 
    27 
    28 
       
    29 const TUint KDefaultHeapSize=0x10000;
    28 const TUint KDefaultHeapSize=0x10000;
    30 
    29 
       
    30 void *gProvider = NULL;
       
    31 RFastLock gProviderFastLock;
    31 
    32 
    32 /**
    33 /**
    33 The server maintains session with the clients. 
    34 The server maintains session with the clients. 
    34 It starts during the initialization of the Content update receiver thread.  
    35 It starts during the initialization of the Content update receiver thread.  
    35 */
    36 */
   349 */	
   350 */	
   350 CUpdateReceiverNotificationBatch* CSurfaceUpdateSession::UpdateReceiverNotificationBatchL()
   351 CUpdateReceiverNotificationBatch* CSurfaceUpdateSession::UpdateReceiverNotificationBatchL()
   351 	{
   352 	{
   352 	TInt numElement = iUpdateReceiverNotificationBatches.Count();
   353 	TInt numElement = iUpdateReceiverNotificationBatches.Count();
   353 	CUpdateReceiverNotificationBatch* notifier = NULL;
   354 	CUpdateReceiverNotificationBatch* notifier = NULL;
       
   355 	CSurfaceUpdateServer* server = (CSurfaceUpdateServer*) Server();
   354 	for(TInt index = 0; index < numElement; index++)
   356 	for(TInt index = 0; index < numElement; index++)
   355 		{
   357 		{
   356 		notifier = iUpdateReceiverNotificationBatches[index];
   358 		notifier = iUpdateReceiverNotificationBatches[index];
   357 		if(notifier->iType == EUpdateSrvReusable)
   359 		if(notifier->iType == EUpdateSrvReusable)
   358 			{
   360 			{
   359 			__ASSERT_ALWAYS(notifier->iMsg.IsNull(), CSurfaceUpdateServer::PanicServer(EUpdateServPanicDataIntegrity));
   361 			__ASSERT_ALWAYS(notifier->iMsg.IsNull(), CSurfaceUpdateServer::PanicServer(EUpdateServPanicDataIntegrity));
       
   362             notifier->SetNumUpdateReceivers(server->NumUpdateReceivers());
   360 			if(numElement > index + 1)
   363 			if(numElement > index + 1)
   361 				{
   364 				{
   362 			//to improve a search, append the element to the end of the array
   365 			//to improve a search, append the element to the end of the array
   363 				iUpdateReceiverNotificationBatches.Remove(index);
   366 				iUpdateReceiverNotificationBatches.Remove(index);
   364 				iUpdateReceiverNotificationBatches.AppendL(notifier);
   367 				iUpdateReceiverNotificationBatches.AppendL(notifier);
   365 				}
   368 				}
   366 			return notifier;
   369 			return notifier;
   367 			}
   370 			}
   368 		}
   371 		}
   369 	
   372 	
   370 	CSurfaceUpdateServer* server = (CSurfaceUpdateServer*) Server();
       
   371 	notifier = new (ELeave) CUpdateReceiverNotificationBatch(this, server->NumUpdateReceivers());
   373 	notifier = new (ELeave) CUpdateReceiverNotificationBatch(this, server->NumUpdateReceivers());
   372 	CleanupStack::PushL(notifier);
   374 	CleanupStack::PushL(notifier);
   373 	iUpdateReceiverNotificationBatches.AppendL(notifier);
   375 	iUpdateReceiverNotificationBatches.AppendL(notifier);
   374 	CleanupStack::Pop();
   376 	CleanupStack::Pop();
   375 	
   377 	
   881 		(static_cast<CSurfaceUpdateServer*> (server))-> iNumberPendingNotification++;
   883 		(static_cast<CSurfaceUpdateServer*> (server))-> iNumberPendingNotification++;
   882 		}
   884 		}
   883 	}
   885 	}
   884 #endif
   886 #endif
   885 
   887 
       
   888 
       
   889 /**
       
   890 Set number of UpdateReceivers - called when update receivers are added/removed.
       
   891 
       
   892 @param aNumUpdateReceivers - new number of update receivers for the batch.
       
   893  */
       
   894 void CUpdateReceiverNotificationBatch::SetNumUpdateReceivers(TInt aNumUpdateReceivers)
       
   895     {
       
   896     __ASSERT_DEBUG(aNumUpdateReceivers >= 0 && aNumUpdateReceivers < 1000 /* arbitrary "large" limit */,
       
   897             CSurfaceUpdateServer::PanicServer(EUpdateServPanicDataIntegrity));
       
   898     __ASSERT_DEBUG(iType == EUpdateSrvReusable, 
       
   899             CSurfaceUpdateServer::PanicServer(EUpdateServPanicDataIntegrity));
       
   900     iNumUpdateReceivers = aNumUpdateReceivers;
       
   901     }
   886 /**
   902 /**
   887 
   903 
   888 The class will be used by composition receiver
   904 The class will be used by composition receiver
   889 */
   905 */
   890 CSurfaceUpdateServerProvider* CSurfaceUpdateServerProvider::NewL(CActive::TPriority aPriority, CSurfaceUpdateServer* aServer)
   906 CSurfaceUpdateServerProvider* CSurfaceUpdateServerProvider::NewL(CActive::TPriority aPriority, CSurfaceUpdateServer* aServer)
   953 #ifdef TEST_SURFACE_UPDATE
   969 #ifdef TEST_SURFACE_UPDATE
   954 	RThread thread;
   970 	RThread thread;
   955 
   971 
   956 	if(thread.Open(iThreadId) == KErrNone)
   972 	if(thread.Open(iThreadId) == KErrNone)
   957 		{
   973 		{
       
   974 	    TInt err = gProviderFastLock.CreateLocal();
       
   975 	    __ASSERT_ALWAYS(err == KErrNone || err == KErrAlreadyExists, CSurfaceUpdateServer::PanicServer(EUpdateServPanicGlobalFastLock));
       
   976 	    
       
   977 	    gProviderFastLock.Wait();
       
   978 	    gProvider = NULL;
   958 		if (iServer)
   979 		if (iServer)
   959 			{
   980 			{
   960 			while((static_cast<CSurfaceUpdateServer*> (iServer))-> iNumberPendingNotification)
   981 			while((static_cast<CSurfaceUpdateServer*> (iServer))-> iNumberPendingNotification)
   961 				User::After(TTimeIntervalMicroSeconds32(1000));
   982 				User::After(TTimeIntervalMicroSeconds32(1000));
   962 			}
   983 			}
   967 		TRequestStatus status1;
   988 		TRequestStatus status1;
   968 		thread.Logon(status1);
   989 		thread.Logon(status1);
   969 		User::WaitForRequest(status1);
   990 		User::WaitForRequest(status1);
   970 		thread.Close();
   991 		thread.Close();
   971 		
   992 		
   972 		Dll::SetTls(NULL);
   993      	gProviderFastLock.Close();
   973 		}
   994 		}
   974 #endif
   995 #endif
   975 	}
   996 	}
   976 
   997 
   977 /**
   998 /**
  1012 		which will be set when the server is started. The variable will be used to registry 
  1033 		which will be set when the server is started. The variable will be used to registry 
  1013 		composition receiver instances. The caller doesn't acquire the ownership of this instance,
  1034 		composition receiver instances. The caller doesn't acquire the ownership of this instance,
  1014 		thus mustn't delete it. The pointer will be valid until server is operating, 
  1035 		thus mustn't delete it. The pointer will be valid until server is operating, 
  1015 		i.e. system is up.
  1036 		i.e. system is up.
  1016 
  1037 
  1017 @panic KErrAccessDenied	If is called from process other than WSERV.	
       
  1018 @return KErrNone if an operation is successful, any other system error codes otherwise
  1038 @return KErrNone if an operation is successful, any other system error codes otherwise
  1019 */
  1039 */
  1020 EXPORT_C TInt StartSurfaceUpdateServer(MSurfaceUpdateServerProvider*& aSurfaceUpdateServerProvider)
  1040 EXPORT_C TInt StartSurfaceUpdateServer(MSurfaceUpdateServerProvider*& aSurfaceUpdateServerProvider)
  1021 	{
  1041 	{
  1022 #ifndef TEST_SURFACE_UPDATE
  1042 #ifndef TEST_SURFACE_UPDATE
  1023 	RProcess process;
       
  1024 	TUidType uidType = process.Type();
       
  1025 	const TInt32 KWservUid = 268450592;
       
  1026 	const TUid& uid1 = uidType[2];
       
  1027 
       
  1028 	if(uid1.iUid != KWservUid) //only wserv process can start the server
       
  1029 		{// some malicious client tries to launch the server
       
  1030 		process.Panic(_L("Access denied"), KErrAccessDenied);
       
  1031 		return KErrAccessDenied;
       
  1032 		}	  
       
  1033 	TPtrC serverName(KSurfaceUpdateServerName);
  1043 	TPtrC serverName(KSurfaceUpdateServerName);
  1034 #else
  1044 #else
  1035 	TPtrC serverName(KTestSurfaceUpdateServerName);
  1045 	TPtrC serverName(KTestSurfaceUpdateServerName);
  1036 #endif
  1046 #endif
  1037 	TAny *provider = Dll::Tls();
  1047 	//locking
       
  1048 	TInt err = gProviderFastLock.CreateLocal();
       
  1049 	
       
  1050 	if (err != KErrNone && err != KErrAlreadyExists)
       
  1051 	    {
       
  1052         return err;
       
  1053 	    }
       
  1054 	
       
  1055 	gProviderFastLock.Wait();
       
  1056 
       
  1057 	TAny *provider = gProvider;
  1038 	if(provider)
  1058 	if(provider)
  1039 		{
  1059 		{
  1040 		aSurfaceUpdateServerProvider = static_cast <MSurfaceUpdateServerProvider*> (provider);
  1060 		aSurfaceUpdateServerProvider = static_cast <MSurfaceUpdateServerProvider*> (provider);
       
  1061 		gProviderFastLock.Signal();
  1041 		return KErrNone;
  1062 		return KErrNone;
  1042 		}
  1063 		}
  1043 	TFullName   name;
  1064 	TFullName   name;
  1044 	RThread serverThread;
  1065 	RThread serverThread;
  1045 	TInt res = KErrAlreadyExists;
  1066 	TInt res = KErrAlreadyExists;
  1052 		TBuf<32> buf;
  1073 		TBuf<32> buf;
  1053 		tm.UniversalTime();
  1074 		tm.UniversalTime();
  1054 		TRAP(res, tm.FormatL(buf, _L("_%H%T%S%C")));
  1075 		TRAP(res, tm.FormatL(buf, _L("_%H%T%S%C")));
  1055 		if(res != KErrNone)	
  1076 		if(res != KErrNone)	
  1056 			{
  1077 			{
       
  1078 			gProviderFastLock.Signal();
  1057 			return res;
  1079 			return res;
  1058 			}
  1080 			}
  1059 		TBuf<128> threadName(serverName);
  1081 		TBuf<128> threadName(serverName);
  1060 		threadName.Append(buf); //guarantee uniqueness  of the thread name
  1082 		threadName.Append(buf); //guarantee uniqueness  of the thread name
  1061 		  // Create the thread for the server.
  1083 		  // Create the thread for the server.
  1075 			serverThread.SetPriority(priority); // The same as the priority of the creating thread
  1097 			serverThread.SetPriority(priority); // The same as the priority of the creating thread
  1076 			serverThread.Rendezvous(rendezvousStatus);
  1098 			serverThread.Rendezvous(rendezvousStatus);
  1077 			serverThread.Resume();
  1099 			serverThread.Resume();
  1078 			User::WaitForRequest(rendezvousStatus);
  1100 			User::WaitForRequest(rendezvousStatus);
  1079 			res = rendezvousStatus.Int();
  1101 			res = rendezvousStatus.Int();
  1080 			Dll::SetTls(aSurfaceUpdateServerProvider);
  1102 			gProvider = aSurfaceUpdateServerProvider;
  1081 			}
  1103 			}
  1082     // The thread has not been created - clearly there's been a problem.
  1104     // The thread has not been created - clearly there's been a problem.
  1083 		else
  1105 		else
  1084 			{
  1106 			{
  1085 			serverThread.Close();
  1107 			serverThread.Close();
  1086 			}
  1108 			}
  1087 		}
  1109 		}
       
  1110        gProviderFastLock.Signal();
  1088 		return res;
  1111 		return res;
  1089 	}
  1112 	}