diff -r c18f9fa7f42e -r 640d30f4fb64 presencecache/presencecachesymbian/presencecacheclient2/src/presencecacheclient.cpp --- a/presencecache/presencecachesymbian/presencecacheclient2/src/presencecacheclient.cpp Fri Oct 08 11:42:51 2010 +0300 +++ b/presencecache/presencecachesymbian/presencecacheclient2/src/presencecacheclient.cpp Fri Oct 15 12:24:46 2010 +0300 @@ -103,54 +103,65 @@ // ----------------------------------------------------------------------------- // CPresenceCacheClient::Connect() -// Connects to the server and create a session. +// Connect to the server, attempting to start it if necessary // ----------------------------------------------------------------------------- // TInt CPresenceCacheClient::Connect() { - TInt error = StartServer(); - - if ( KErrNone == error ) + TInt retry=2; + for (;;) { - error = CreateSession( NName::KSymbianServer, - Version(), - NRequest::KMsgSlotCount ); - } - return error; + TInt r = CreateSession( NName::KSymbianServer, + Version(), + NRequest::KMsgSlotCount ); + // Continue if there was error but caused from server not being + // started yet, in which case server start will be tried later in the loop. + // Otherwise return KErrNone or one of the system wide error codes. + if (r!=KErrNotFound && r!=KErrServerTerminated) + return r; + // + // Decreace retry counter and abort if too many retries already + if (--retry==0) + return r; + // + // Try to start server. If no error or the error was caused + // from server already started, continue to next iteration when + // the session creation will be tried again. + r=StartServer(); + if (r!=KErrNone && r!=KErrAlreadyExists) + return r; + + } } // ---------------------------------------------------- // CPresenceCacheClient::StartServer -// // ---------------------------------------------------- // TInt CPresenceCacheClient::StartServer() - { - TInt result; - TRequestStatus status = KRequestPending; - - TFindServer findCacheServer( NName::KSymbianServer ); - TFullName name; - - result = findCacheServer.Next( name ); - if ( result == KErrNone ) - { - // Server already running - return KErrNone; - } - + { + // Start the server process. Simultaneous launching + // of two such processes should be detected when the second one attempts to + // create the server object, failing with KErrAlreadyExists. + // RProcess server; - result = server.Create( NName::KExecutable, KNullDesC ); - if( result != KErrNone ) - return result; - server.Rendezvous( status ); - status != KRequestPending ? server.Kill( 0 ) : server.Resume(); - //Wait for start or death - User::WaitForRequest( status ); - result = server.ExitType() == EExitPanic ? KErrGeneral : status.Int(); - server.Close(); - - return result; + TInt r=server.Create( NName::KExecutable, KNullDesC ); + if (r!=KErrNone) + return r; + TRequestStatus stat; + server.Rendezvous(stat); + if (stat!=KRequestPending) + server.Kill(0); // abort startup + else + server.Resume(); // logon OK - start the server + User::WaitForRequest(stat); // wait for start or death + // we can't use the 'exit reason' if the server panicked as this + // is the panic 'reason' and may be '0' which cannot be distinguished + // from KErrNone + r=(server.ExitType()==EExitPanic) ? KErrGeneral : stat.Int(); + // here it may return KErrAlreadyExists or KErrNone + server.Close(); + return r; } // -----------------------------------------------------------------------------