examples/S60CppExamples/ClientServerAsync/server/src/timeserver.cpp

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

Generated by  doxygen 1.6.2