00001 /* 00002 * ============================================================================== 00003 * Name : timeserver.cpp 00004 * Part of : CSAsync 00005 * Interface : 00006 * Description : 00007 * Version : 00008 * 00009 * Copyright (c) 2004-2006 Nokia Corporation and/or its subsidiary(-ies). 00010 * All rights reserved. 00011 * This component and the accompanying materials are made available 00012 * under the terms of "Eclipse Public License v1.0" 00013 * which accompanies this distribution, and is available 00014 * at the URL "http://www.eclipse.org/legal/epl-v10.html". 00015 * ============================================================================== 00016 */ 00017 00018 00019 // INCLUDE FILES 00020 #include <e32svr.h> 00021 #include <e32math.h> 00022 00023 #include "TimeServer.h" 00024 #include "ClientServerCommon.h" 00025 #include "TimeSession.h" 00026 00027 // ========================= MEMBER FUNCTIONS ================================== 00028 00029 // ----------------------------------------------------------------------------- 00030 // CTimeServer::NewL() 00031 // Two-phased constructor. 00032 // ----------------------------------------------------------------------------- 00033 // 00034 CTimeServer* CTimeServer::NewL() 00035 { 00036 CTimeServer* timeServer = CTimeServer::NewLC(); 00037 CleanupStack::Pop( timeServer ); 00038 return timeServer; 00039 } 00040 00041 // ----------------------------------------------------------------------------- 00042 // CTimeServer::NewLC() 00043 // Two-phased constructor. 00044 // ----------------------------------------------------------------------------- 00045 // 00046 CTimeServer* CTimeServer::NewLC() 00047 { 00048 CTimeServer* timeServer = new ( ELeave ) CTimeServer( EPriorityNormal ); 00049 CleanupStack::PushL( timeServer ); 00050 timeServer->ConstructL(); 00051 return timeServer; 00052 } 00053 00054 // ----------------------------------------------------------------------------- 00055 // CTimeServer::ConstructL() 00056 // Symbian 2nd phase constructor can leave. 00057 // ----------------------------------------------------------------------------- 00058 // 00059 void CTimeServer::ConstructL() 00060 { 00061 StartL( KTimeServerName ); 00062 } 00063 00064 // ----------------------------------------------------------------------------- 00065 // CTimeServer::CTimeServer() 00066 // C++ default constructor can NOT contain any code, that might leave. 00067 // ----------------------------------------------------------------------------- 00068 // 00069 CTimeServer::CTimeServer( TInt aPriority ) 00070 : CServer2( aPriority ) 00071 { 00072 // Implementation not required 00073 } 00074 00075 // ----------------------------------------------------------------------------- 00076 // CTimeServer::~CTimeServer() 00077 // Destructor. 00078 // ----------------------------------------------------------------------------- 00079 // 00080 CTimeServer::~CTimeServer() 00081 { 00082 delete iHeartbeat; 00083 iHeartbeat = NULL; 00084 } 00085 00086 // ----------------------------------------------------------------------------- 00087 // CTimeServer::NewSessionL() 00088 // Creates a time server session. 00089 // ----------------------------------------------------------------------------- 00090 // 00091 CSession2* CTimeServer::NewSessionL( const TVersion& aVersion, 00092 const RMessage2& /*aMessage*/ ) const 00093 { 00094 // Check we are the right version 00095 if ( !User::QueryVersionSupported( TVersion( KTimeServMajorVersionNumber, 00096 KTimeServMinorVersionNumber, 00097 KTimeServBuildVersionNumber ), 00098 aVersion ) ) 00099 { 00100 User::Leave( KErrNotSupported ); 00101 } 00102 00103 // Make new session 00104 //RThread client = Message().Client(); 00105 return CTimeServerSession::NewL( *const_cast<CTimeServer*> ( this ) ); 00106 } 00107 00108 // ----------------------------------------------------------------------------- 00109 // CTimeServer::IncrementSessions() 00110 // Increments the count of the active sessions for this server. 00111 // ----------------------------------------------------------------------------- 00112 // 00113 void CTimeServer::IncrementSessions() 00114 { 00115 iSessionCount++; 00116 } 00117 00118 // ----------------------------------------------------------------------------- 00119 // CTimeServer::DecrementSessions() 00120 // Decrements the count of the active sessions for this server. 00121 // ----------------------------------------------------------------------------- 00122 // 00123 void CTimeServer::DecrementSessions() 00124 { 00125 iSessionCount--; 00126 if ( iSessionCount <= 0 ) 00127 { 00128 CActiveScheduler::Stop(); 00129 } 00130 } 00131 00132 // ----------------------------------------------------------------------------- 00133 // CTimeServer::RunError() 00134 // Processes any errors. 00135 // ----------------------------------------------------------------------------- 00136 // 00137 TInt CTimeServer::RunError( TInt aError ) 00138 { 00139 if ( aError == KErrBadDescriptor ) 00140 { 00141 // A bad descriptor error implies a badly programmed client, 00142 // so panic it; otherwise report the error to the client 00143 PanicClient( Message(), EBadDescriptor ); 00144 } 00145 else 00146 { 00147 Message().Complete( aError ); 00148 } 00149 00150 // The leave will result in an early return from CServer::RunL(), skipping 00151 // the call to request another message. So do that now in order to keep the 00152 // server running. 00153 ReStart(); 00154 00155 return KErrNone; // Handled the error fully 00156 } 00157 00158 // ----------------------------------------------------------------------------- 00159 // CTimeServer::PanicClient() 00160 // Panics the client. 00161 // ----------------------------------------------------------------------------- 00162 // 00163 void CTimeServer::PanicClient( const RMessage2& aMessage, TTimeServPanic aPanic ) 00164 { 00165 aMessage.Panic( KCSAsyncServer, aPanic ); 00166 } 00167 00168 // ----------------------------------------------------------------------------- 00169 // CTimeServer::PanicServer() 00170 // Panics the server. 00171 // ----------------------------------------------------------------------------- 00172 // 00173 void CTimeServer::PanicServer( TTimeServPanic aPanic ) 00174 { 00175 User::Panic( KCSAsyncServer, aPanic ); 00176 } 00177 00178 // ----------------------------------------------------------------------------- 00179 // CTimeServer::WaitForTickL() 00180 // Activates the heartbeat. 00181 // ----------------------------------------------------------------------------- 00182 // 00183 void CTimeServer::WaitForTickL() 00184 { 00185 if ( !iHeartbeat ) 00186 { 00187 iHeartbeat = CHeartbeat::NewL( EPriorityHigh ); 00188 iHeartbeat->Start( ETwelveOClock, this ); 00189 } 00190 } 00191 00192 // ----------------------------------------------------------------------------- 00193 // CTimeServer::Beat() 00194 // A clock tick has occured. 00195 // ----------------------------------------------------------------------------- 00196 // 00197 void CTimeServer::Beat() 00198 { 00199 SendTimeToSessions(); 00200 } 00201 00202 // ----------------------------------------------------------------------------- 00203 // CTimeServer::Synchronize() 00204 // Several clock ticks have occured. 00205 // ----------------------------------------------------------------------------- 00206 // 00207 void CTimeServer::Synchronize() 00208 { 00209 SendTimeToSessions(); 00210 } 00211 00212 // ----------------------------------------------------------------------------- 00213 // CTimeServer::SendTimeToSessions() 00214 // Informs all the clients that a time change has occured. 00215 // ----------------------------------------------------------------------------- 00216 // 00217 void CTimeServer::SendTimeToSessions() 00218 { 00219 iSessionIter.SetToFirst(); 00220 CTimeServerSession* session; 00221 session = reinterpret_cast<CTimeServerSession*>( iSessionIter++ ); 00222 while ( session ) 00223 { 00224 session->SendTimeToClient(); 00225 session = reinterpret_cast<CTimeServerSession*>( iSessionIter++ ); 00226 } 00227 } 00228 00229 // ----------------------------------------------------------------------------- 00230 // CTimeServer::ThreadFunctionL() 00231 // Second stage startup for the server thread. 00232 // ----------------------------------------------------------------------------- 00233 // 00234 void CTimeServer::ThreadFunctionL() 00235 { 00236 // Construct active scheduler 00237 CActiveScheduler* activeScheduler = new ( ELeave ) CActiveScheduler; 00238 CleanupStack::PushL( activeScheduler ); 00239 00240 // Install active scheduler 00241 // We don't need to check whether an active scheduler is already installed 00242 // as this is a new thread, so there won't be one 00243 CActiveScheduler::Install( activeScheduler ); 00244 00245 // Construct our server 00246 CTimeServer::NewLC(); // Anonymous 00247 00248 RSemaphore semaphore; 00249 User::LeaveIfError( semaphore.OpenGlobal( KTimeServerSemaphoreName ) ); 00250 00251 // Semaphore opened ok 00252 semaphore.Signal(); 00253 semaphore.Close(); 00254 00255 // Start handling requests 00256 CActiveScheduler::Start(); 00257 00258 CleanupStack::PopAndDestroy( 2, activeScheduler ); //Anonymous CTimeServer 00259 } 00260 00261 // ----------------------------------------------------------------------------- 00262 // CTimeServer::ThreadFunction() 00263 // Main function for the server thread. 00264 // ----------------------------------------------------------------------------- 00265 // 00266 TInt CTimeServer::ThreadFunction( TAny* /*aNone*/ ) 00267 { 00268 CTrapCleanup* cleanupStack = CTrapCleanup::New(); 00269 if ( !( cleanupStack ) ) 00270 { 00271 PanicServer( ECreateTrapCleanup ); 00272 } 00273 00274 TRAPD( err, ThreadFunctionL() ); 00275 if ( err != KErrNone ) 00276 { 00277 PanicServer( ESrvCreateServer ); 00278 } 00279 00280 delete cleanupStack; 00281 cleanupStack = NULL; 00282 00283 return KErrNone; 00284 } 00285 00286 00287 // ----------------------------------------------------------------------------- 00288 // E32Main() 00289 // Provides the API for the operating system to start the executable. 00290 // Returns the address of the function to be called. 00291 // ----------------------------------------------------------------------------- 00292 // 00293 TInt E32Main() 00294 { 00295 return CTimeServer::ThreadFunction( NULL ); 00296 } 00297 00298 00299 00300 // End of File