00001 /* 00002 * ============================================================================== 00003 * Name : timeserver.cpp 00004 * Part of : CSSync 00005 * Interface : 00006 * Description : 00007 * Version : 00008 * 00009 * Copyright (c) 2006 Nokia Corporation. 00010 * This material, including documentation and any related 00011 * computer programs, is protected by copyright controlled by 00012 * Nokia Corporation. 00013 * ============================================================================== 00014 */ 00015 00016 00017 // INCLUDE FILES 00018 #include <eikstart.h> 00019 #include <e32svr.h> 00020 #include <e32math.h> 00021 00022 #include "TimeServer.h" 00023 #include "ClientServerCommon.h" 00024 #include "TimeSession.h" 00025 00026 // ========================= MEMBER FUNCTIONS ================================== 00027 00028 // ----------------------------------------------------------------------------- 00029 // CTimeServer::NewL() 00030 // Two-phased constructor. 00031 // ----------------------------------------------------------------------------- 00032 // 00033 CTimeServer* CTimeServer::NewL() 00034 { 00035 CTimeServer* timeServer = CTimeServer::NewLC(); 00036 CleanupStack::Pop( timeServer ); 00037 return timeServer; 00038 } 00039 00040 // ----------------------------------------------------------------------------- 00041 // CTimeServer::NewLC() 00042 // Two-phased constructor. 00043 // ----------------------------------------------------------------------------- 00044 // 00045 CTimeServer* CTimeServer::NewLC() 00046 { 00047 CTimeServer* timeServer = new ( ELeave ) CTimeServer( EPriorityNormal ); 00048 CleanupStack::PushL( timeServer ); 00049 timeServer->ConstructL(); 00050 return timeServer; 00051 } 00052 00053 // ----------------------------------------------------------------------------- 00054 // CTimeServer::ConstructL() 00055 // Symbian 2nd phase constructor can leave. 00056 // ----------------------------------------------------------------------------- 00057 // 00058 void CTimeServer::ConstructL() 00059 { 00060 StartL( KTimeServerName ); 00061 } 00062 00063 // ----------------------------------------------------------------------------- 00064 // CTimeServer::CTimeServer() 00065 // C++ default constructor can NOT contain any code, that might leave. 00066 // ----------------------------------------------------------------------------- 00067 // 00068 CTimeServer::CTimeServer( TInt aPriority ) 00069 : CServer2( aPriority ) 00070 { 00071 // Implementation not required 00072 } 00073 00074 // ----------------------------------------------------------------------------- 00075 // CTimeServer::NewSessionL() 00076 // Creates a time server session. 00077 // ----------------------------------------------------------------------------- 00078 // 00079 CSession2* CTimeServer::NewSessionL( const TVersion& aVersion, 00080 const RMessage2& /*aMessage*/ ) const 00081 { 00082 // Check we are the right version 00083 if ( !User::QueryVersionSupported( TVersion( KTimeServMajorVersionNumber, 00084 KTimeServMinorVersionNumber, 00085 KTimeServBuildVersionNumber ), 00086 aVersion ) ) 00087 { 00088 User::Leave( KErrNotSupported ); 00089 } 00090 00091 // Make new session 00092 return CTimeServerSession::NewL( *const_cast<CTimeServer*> ( this ) ); 00093 } 00094 00095 // ----------------------------------------------------------------------------- 00096 // CTimeServer::IncrementSessions() 00097 // Increments the count of the active sessions for this server. 00098 // ----------------------------------------------------------------------------- 00099 // 00100 void CTimeServer::IncrementSessions() 00101 { 00102 iSessionCount++; 00103 } 00104 00105 // ----------------------------------------------------------------------------- 00106 // CTimeServer::DecrementSessions() 00107 // Decrements the count of the active sessions for this server. 00108 // ----------------------------------------------------------------------------- 00109 // 00110 void CTimeServer::DecrementSessions() 00111 { 00112 iSessionCount--; 00113 if ( iSessionCount <= 0 ) 00114 { 00115 CActiveScheduler::Stop(); 00116 } 00117 } 00118 00119 // ----------------------------------------------------------------------------- 00120 // CTimeServer::RunError() 00121 // Processes any errors. 00122 // ----------------------------------------------------------------------------- 00123 // 00124 TInt CTimeServer::RunError( TInt aError ) 00125 { 00126 if ( aError == KErrBadDescriptor ) 00127 { 00128 // A bad descriptor error implies a badly programmed client, 00129 // so panic it; otherwise report the error to the client 00130 PanicClient( Message(), EBadDescriptor ); 00131 } 00132 else 00133 { 00134 Message().Complete( aError ); 00135 } 00136 00137 // The leave will result in an early return from CServer::RunL(), skipping 00138 // the call to request another message. So do that now in order to keep the 00139 // server running. 00140 ReStart(); 00141 00142 return KErrNone; // Handled the error fully 00143 } 00144 00145 // ----------------------------------------------------------------------------- 00146 // CTimeServer::PanicClient() 00147 // Panics the client. 00148 // ----------------------------------------------------------------------------- 00149 // 00150 void CTimeServer::PanicClient( const RMessage2& aMessage, TTimeServPanic aPanic ) 00151 { 00152 aMessage.Panic( KCSSyncServer, aPanic ); 00153 } 00154 00155 // ----------------------------------------------------------------------------- 00156 // CTimeServer::PanicServer() 00157 // Panics the server. 00158 // ----------------------------------------------------------------------------- 00159 // 00160 void CTimeServer::PanicServer( TTimeServPanic aPanic ) 00161 { 00162 User::Panic( KCSSyncServer, aPanic ); 00163 } 00164 00165 // ----------------------------------------------------------------------------- 00166 // CTimeServer::ThreadFunctionL() 00167 // Second stage startup for the server thread. 00168 // ----------------------------------------------------------------------------- 00169 // 00170 void CTimeServer::ThreadFunctionL() 00171 { 00172 // Construct active scheduler 00173 CActiveScheduler* activeScheduler = new ( ELeave ) CActiveScheduler; 00174 CleanupStack::PushL( activeScheduler ); 00175 00176 // Install active scheduler 00177 // We don't need to check whether an active scheduler is already installed 00178 // as this is a new thread, so there won't be one 00179 CActiveScheduler::Install( activeScheduler ); 00180 00181 // Construct our server 00182 CTimeServer::NewLC(); // Anonymous 00183 00184 RSemaphore semaphore; 00185 User::LeaveIfError( semaphore.OpenGlobal( KTimeServerSemaphoreName ) ); 00186 00187 // Semaphore opened ok 00188 semaphore.Signal(); 00189 semaphore.Close(); 00190 00191 // Start handling requests 00192 CActiveScheduler::Start(); 00193 00194 CleanupStack::PopAndDestroy( 2, activeScheduler ); //Anonymous CTimeServer 00195 } 00196 00197 // ----------------------------------------------------------------------------- 00198 // CTimeServer::ThreadFunction() 00199 // Main function for the server thread. 00200 // ----------------------------------------------------------------------------- 00201 // 00202 TInt CTimeServer::ThreadFunction( TAny* /*aNone*/ ) 00203 { 00204 CTrapCleanup* cleanupStack = CTrapCleanup::New(); 00205 if ( !( cleanupStack ) ) 00206 { 00207 PanicServer( ECreateTrapCleanup ); 00208 } 00209 00210 TRAPD( err, ThreadFunctionL() ); 00211 if ( err != KErrNone ) 00212 { 00213 PanicServer( ESrvCreateServer ); 00214 } 00215 00216 delete cleanupStack; 00217 cleanupStack = NULL; 00218 00219 return KErrNone; 00220 } 00221 00222 // ----------------------------------------------------------------------------- 00223 // E32Main() 00224 // Provides the API for the operating system to start the executable. 00225 // Returns the address of the function to be called. 00226 // ----------------------------------------------------------------------------- 00227 // 00228 TInt E32Main() 00229 { 00230 return CTimeServer::ThreadFunction( NULL ); 00231 } 00232 00233 00234 00235 // End of File