graphicscomposition/surfaceupdate/src/surfaceupdateserver.cpp
branchRCL_3
changeset 19 bbf46f59e123
parent 10 0e9202c0340c
child 20 25ffed67c7ef
equal deleted inserted replaced
18:57c618273d5c 19:bbf46f59e123
    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 /**
  1017 @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
  1018 */
  1039 */
  1019 EXPORT_C TInt StartSurfaceUpdateServer(MSurfaceUpdateServerProvider*& aSurfaceUpdateServerProvider)
  1040 EXPORT_C TInt StartSurfaceUpdateServer(MSurfaceUpdateServerProvider*& aSurfaceUpdateServerProvider)
  1020 	{
  1041 	{
  1021 #ifndef TEST_SURFACE_UPDATE
  1042 #ifndef TEST_SURFACE_UPDATE
  1022     TPtrC serverName(KSurfaceUpdateServerName);
  1043 	TPtrC serverName(KSurfaceUpdateServerName);
  1023 #else
  1044 #else
  1024     TPtrC serverName(KTestSurfaceUpdateServerName);
  1045 	TPtrC serverName(KTestSurfaceUpdateServerName);
  1025 #endif    
  1046 #endif
  1026 	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;
  1027 	if(provider)
  1058 	if(provider)
  1028 		{
  1059 		{
  1029 		aSurfaceUpdateServerProvider = static_cast <MSurfaceUpdateServerProvider*> (provider);
  1060 		aSurfaceUpdateServerProvider = static_cast <MSurfaceUpdateServerProvider*> (provider);
       
  1061 		gProviderFastLock.Signal();
  1030 		return KErrNone;
  1062 		return KErrNone;
  1031 		}
  1063 		}
  1032 	TFullName   name;
  1064 	TFullName   name;
  1033 	RThread serverThread;
  1065 	RThread serverThread;
  1034 	TInt res = KErrAlreadyExists;
  1066 	TInt res = KErrAlreadyExists;
  1041 		TBuf<32> buf;
  1073 		TBuf<32> buf;
  1042 		tm.UniversalTime();
  1074 		tm.UniversalTime();
  1043 		TRAP(res, tm.FormatL(buf, _L("_%H%T%S%C")));
  1075 		TRAP(res, tm.FormatL(buf, _L("_%H%T%S%C")));
  1044 		if(res != KErrNone)	
  1076 		if(res != KErrNone)	
  1045 			{
  1077 			{
       
  1078 			gProviderFastLock.Signal();
  1046 			return res;
  1079 			return res;
  1047 			}
  1080 			}
  1048 		TBuf<128> threadName(serverName);
  1081 		TBuf<128> threadName(serverName);
  1049 		threadName.Append(buf); //guarantee uniqueness  of the thread name
  1082 		threadName.Append(buf); //guarantee uniqueness  of the thread name
  1050 		  // Create the thread for the server.
  1083 		  // Create the thread for the server.
  1064 			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
  1065 			serverThread.Rendezvous(rendezvousStatus);
  1098 			serverThread.Rendezvous(rendezvousStatus);
  1066 			serverThread.Resume();
  1099 			serverThread.Resume();
  1067 			User::WaitForRequest(rendezvousStatus);
  1100 			User::WaitForRequest(rendezvousStatus);
  1068 			res = rendezvousStatus.Int();
  1101 			res = rendezvousStatus.Int();
  1069 			Dll::SetTls(aSurfaceUpdateServerProvider);
  1102 			gProvider = aSurfaceUpdateServerProvider;
  1070 			}
  1103 			}
  1071     // 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.
  1072 		else
  1105 		else
  1073 			{
  1106 			{
  1074 			serverThread.Close();
  1107 			serverThread.Close();
  1075 			}
  1108 			}
  1076 		}
  1109 		}
       
  1110        gProviderFastLock.Signal();
  1077 		return res;
  1111 		return res;
  1078 	}
  1112 	}