examples/SDKExamples/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 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

Generated by  doxygen 1.6.2