--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ncdengine/engine/src/catalogsclientserverserver.cpp Tue Jan 26 12:06:03 2010 +0200
@@ -0,0 +1,526 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Implementation of CCatalogsClientServerServer
+*
+*/
+
+
+#include "catalogsclientserverserver.h"
+#include "catalogsclientserverserversession.h"
+#include "catalogsserverdefines.h"
+#include "catalogsserverengine.h"
+#include "catalogscontext.h"
+
+#include "catalogsdebug.h"
+
+CCatalogsClientServerServer* CCatalogsClientServerServer::iCatalogsServer = NULL;
+
+// Replaced with USE_BUILD_SCRIPT when using build script
+#define DUMMY_DEFINE
+
+#ifdef CATALOGS_UNDERTAKER
+#ifdef USE_BUILD_SCRIPT
+_LIT( KCatalogsUndertakerFilename, "ncdundertaker_APP_NAME_POSTFIX" );
+#else
+_LIT( KCatalogsUndertakerFilename, "ncdundertaker_20019119" );
+#endif // USE_BUILD_SCRIPT
+#endif
+
+// Capability set required from clients. Consists of CAP_APPLICATION capability set.
+static _LIT_SECURITY_POLICY_C7(
+ KCatalogsServerConnectPolicy1,
+ ECapabilityNetworkServices,
+ ECapabilityLocalServices,
+ ECapabilityLocation,
+ ECapabilityReadUserData,
+ ECapabilityWriteUserData,
+ ECapabilityReadDeviceData,
+ ECapabilityWriteDeviceData );
+
+static _LIT_SECURITY_POLICY_C2(
+ KCatalogsServerConnectPolicy2,
+ ECapabilitySwEvent,
+ ECapabilityUserEnvironment );
+
+// ======== MEMBER FUNCTIONS ========
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+CCatalogsClientServerServer* CCatalogsClientServerServer::NewLC()
+ {
+ CCatalogsClientServerServer* self = new( ELeave )
+ CCatalogsClientServerServer( CActive::EPriorityLow - 20 );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+CCatalogsClientServerServer::CCatalogsClientServerServer( TInt aPriority ) :
+ CServer2( aPriority )
+ {
+ iCatalogsServer = this;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+CCatalogsClientServerServer::~CCatalogsClientServerServer()
+ {
+ DLTRACEIN((""));
+ // Usually at this point all sessions are already destroyed.
+ // If not, we have to go through all sessions and destroy
+ // all references to the objects to which references might be lost
+ // if the engine was destroyed first.
+ // Also when doing it this way when the engine is destroyed,
+ // provider can do the final killing of those objects
+ iSessionIter.SetToFirst();
+ CSession2* baseSession = NULL;
+ CCatalogsClientServerServerSession* session = NULL;
+ baseSession = iSessionIter++;
+ while ( baseSession != NULL )
+ {
+ DLTRACE(("Calling ClientSideSessionDown"));
+ // When going down, act as the client side would have died
+ // ->call ClientSideSessionDown for each session
+ session =
+ static_cast<CCatalogsClientServerServerSession*>( baseSession );
+ session->ClientSideSessionDown();
+ baseSession = iSessionIter++;
+ DLTRACE(("ClientSideSessionDown called"));
+ }
+
+ DLTRACE(("Delete engine"));
+ // This is destroyed before destroying container, so possible
+ // resources are freed in its destructor and from the container
+ // in here.
+ // Other way would end up destroying already destroyed stuff.
+ delete iEngine;
+
+ DLTRACE(("Engine deleted"));
+ iShutdownOperations.ResetAndDestroy();
+
+ // If container is going to be removed, it has to be done before
+ // it is destroyed by destroying the container index.
+ if ( iContainer != NULL )
+ {
+ DLTRACE(("Remove container"));
+ RemoveContainer( iContainer );
+ DLTRACE(("Container removed"));
+ }
+ iContainer = NULL;
+
+ DLTRACE(("Deleting container index"));
+ delete iContainerIndex;
+
+#ifdef CATALOGS_UNDERTAKER
+
+ iUndertakerProcess.Close();
+
+#endif
+
+ DLTRACEOUT((""));
+ }
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CCatalogsClientServerServer::ConstructL()
+ {
+ DLTRACEIN((""));
+ User::LeaveIfError( User::RenameThread( KCatalogsServerName ) );
+#ifdef CATALOGS_UNDERTAKER
+
+ DLINFO(( "Creating undertaker process" ));
+ TInt err = iUndertakerProcess.Create( KCatalogsUndertakerFilename, KNullDesC() );
+ if( err != KErrNone )
+ {
+ DLERROR(( "Creating undertaker process failed with %d", err ));
+ }
+ iUndertakerProcess.SetPriority( (TProcessPriority)450 ); // EPriorityHigh
+
+ RThread thisThread;
+ DLINFO(( _L("Setting undertaker parameter 15 as %S"), &thisThread.FullName() ));
+
+ err = iUndertakerProcess.SetParameter( 15, thisThread.FullName() );
+ if( err != KErrNone )
+ {
+ DLERROR(( "Parameter setting failed with %d", err ));
+ }
+ thisThread.Close();
+ iUndertakerProcess.Resume();
+
+#endif
+
+ iContainerIndex = CObjectConIx::NewL();
+ iContainer = NewContainerL();
+
+ iEngine = CCatalogsServerEngine::NewL();
+ // Add the server to the active scheduler
+ StartL( KCatalogsServerName );
+ DLTRACEOUT((""));
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CCatalogsClientServerServer::IncrementSessions()
+ {
+ iSessionCount++;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CCatalogsClientServerServer::DecrementSessions()
+ {
+ iSessionCount--;
+
+ // No more clients, shutdown
+ if ( iSessionCount <= 0 )
+ {
+ CActiveScheduler::Stop();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CCatalogsClientServerServer::HandleSessionRemoval(
+ MCatalogsSession& aSession )
+ {
+ DASSERT( iEngine );
+
+ // We don't want to go further unless the context has been created
+ if ( aSession.ContextPtr() )
+ {
+ iEngine->HandleSessionRemoval( aSession );
+ // Execute shutdown operations
+ OperateShutdownOperations( aSession.Context(), ETrue );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+CObjectCon* CCatalogsClientServerServer::NewContainerL()
+ {
+ // Return a new object container
+ return iContainerIndex->CreateL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CCatalogsClientServerServer::RemoveContainer( CObjectCon* aCon )
+ {
+ DASSERT( iContainerIndex );
+ iContainerIndex->Remove( aCon );
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CCatalogsClientServerServer::CreateProviderL(
+ MCatalogsSession& aSession,
+ TInt aProviderIdentifier,
+ TInt& aHandle,
+ TUint32 aProviderOptions )
+ {
+ DLTRACEIN((""));
+
+ iEngine->CreateProviderL( aSession,
+ aProviderIdentifier,
+ aHandle,
+ aProviderOptions );
+
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TInt CCatalogsClientServerServer::NewInstanceId()
+ {
+ DLTRACEIN((""));
+ return iSessionInstanceIdCounter++;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CCatalogsClientServerServer::AddObjectToContainerL( CObject* aObject )
+ {
+ // If possible, change trap-implementation to something else.
+ // This is just a simple way to do this.
+ TRAPD( err, iContainer->AddL( aObject ) );
+ DLTRACE(("err: %d", err ));
+ if ( err == KErrAlreadyExists || err == KErrNone )
+ {
+ return;
+ }
+ else
+ {
+ User::Leave( err );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CCatalogsClientServerServer::ThreadFunctionL()
+ {
+ DLTRACEIN((""));
+ DCHECK_HEAP
+ // Construct an active scheduler for the server
+
+ DLINFO(( "Creating active schduler" ));
+ CActiveScheduler* activeScheduler = new (ELeave) CActiveScheduler;
+ CleanupStack::PushL( activeScheduler );
+
+ // Install active scheduler
+ // No need to check whether an active scheduler is already installed
+ // as this is a new thread, so there won't be one
+ DLINFO(( "Installing active schduler" ));
+ CActiveScheduler::Install( activeScheduler );
+
+ // Construct our server
+ CCatalogsClientServerServer::NewLC(); // anonymous
+
+ DLINFO(( "Opening semaphore" ));
+ RSemaphore semaphore;
+ User::LeaveIfError(
+ semaphore.OpenGlobal( KCatalogsServerSemaphoreName ));
+
+ DLINFO(( "Signalling and closing semaphore" ));
+ // Semaphore opened ok
+ semaphore.Signal();
+ semaphore.Close();
+
+ // Start handling requests, operation will stop here until
+ // the server dies
+ CActiveScheduler::Start();
+
+ DLINFO(("Server has shut down"));
+
+ // The server has been shut down, clean up
+ CleanupStack::PopAndDestroy( 2, activeScheduler );
+ DLTRACEOUT((""));
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TInt CCatalogsClientServerServer::ThreadFunction( TAny* /*aNone*/ )
+ {
+#ifdef CATALOGS_BUILD_CONFIG_HEAP_MARKS
+ __UHEAP_MARK;
+#endif
+ DLINIT;
+
+ DLTRACEIN((""));
+
+ CTrapCleanup* cleanupStack = CTrapCleanup::New();
+ TRAPD( err, ThreadFunctionL() );
+
+ DLTRACE(( "err: %d", err ));
+ delete cleanupStack;
+ cleanupStack = NULL;
+
+ DLTRACEOUT((""));
+
+ DLUNINIT;
+#ifdef CATALOGS_BUILD_CONFIG_HEAP_MARKS
+ __UHEAP_MARKEND;
+#endif
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TInt CCatalogsClientServerServer::RunError( TInt aError )
+ {
+ DLTRACEIN(( "aError=%d", aError ));
+
+ // Complete the message being processed, although the state of
+ // the server is undetermined
+ DLERROR(( "Completing last message with %d", aError ));
+ Message().Complete( aError );
+
+ DLTRACEOUT(("KErrNone"));
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+CSession2* CCatalogsClientServerServer::NewSessionL(
+ const TVersion& aVersion,
+ const RMessage2& aMsg ) const
+ {
+ DLTRACEIN((""));
+
+ // Check whether the server is compatible with the
+ // requested version
+ if ( !User::QueryVersionSupported(
+ TVersion(
+ KCatalogsServerMajorVersionNumber,
+ KCatalogsServerMinorVersionNumber,
+ KCatalogsServerBuildVersionNumber
+ ),
+ aVersion))
+ {
+ User::Leave( KErrNotSupported );
+ }
+
+ DLINFO(("Checking client capabilities"));
+ // Check the client for required capabilities
+ if (!KCatalogsServerConnectPolicy1().CheckPolicy(
+ aMsg, __PLATSEC_DIAGNOSTIC_STRING("CCatalogsClientServerServer::NewSessionL, KCatalogsServerConnectPolicy1") ) ||
+ !KCatalogsServerConnectPolicy2().CheckPolicy(
+ aMsg, __PLATSEC_DIAGNOSTIC_STRING("CCatalogsClientServerServer::NewSessionL, KCatalogsServerConnectPolicy2" ) ) )
+ {
+ DLINFO(("Client capability check failed"));
+ User::Leave( KErrPermissionDenied );
+ }
+
+ // Context is not created here for the session, because
+ // user given uid cannot be received by this function from
+ // the client-side and it is nicer to create the whole
+ // context-object in one place.
+
+ DLTRACEOUT((""));
+
+ // Create a new session
+ RThread client;
+ return CCatalogsClientServerServerSession::NewL(
+ client,
+ *const_cast<CCatalogsClientServerServer*>( this ) );
+ }
+
+
+/**
+ * Platform dependant entry points
+ */
+
+IMPORT_C TInt WinsMain();
+EXPORT_C TInt WinsMain()
+ {
+ // WINS DLL entry-point. Just return the real thread function
+ // cast to TInt
+ return reinterpret_cast<TInt>(
+ &CCatalogsClientServerServer::ThreadFunction );
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+GLDEF_C TInt E32Main()
+ {
+ return CCatalogsClientServerServer::ThreadFunction( NULL );
+ }
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TInt CCatalogsClientServerServer::AddShutdownOperation(
+ CCatalogsShutdownOperation* aOperation )
+ {
+ DLTRACEIN((""))
+ DASSERT( aOperation );
+ TInt err = iCatalogsServer->iShutdownOperations.Append( aOperation );
+
+ if ( err == KErrNone )
+ {
+ aOperation->SetObserver( *iCatalogsServer );
+ iCatalogsServer->IncrementSessions();
+ }
+ else
+ {
+ DLERROR(("Appending failed: %d", err));
+ delete aOperation;
+ }
+
+ return err;
+ }
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CCatalogsClientServerServer::ShutdownOperationComplete(
+ CCatalogsShutdownOperation* aOperation,
+ TInt aError )
+ {
+ DLTRACEIN(("aError: %d", aError));
+ (void) aError;
+ iShutdownOperations.Remove( iShutdownOperations.Find( aOperation ) );
+ delete aOperation;
+ DecrementSessions();
+ }
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CCatalogsClientServerServer::OperateShutdownOperations(
+ const MCatalogsContext& aContext,
+ TBool aExecute )
+ {
+ DLTRACEIN((""));
+ TInt count = iShutdownOperations.Count();
+ const TUid uid( aContext.FamilyId() );
+ // Iterating backwards because an executed operation may be removed
+ // from the queue while we are iterating through it
+ while( count-- )
+ {
+ if ( iShutdownOperations[ count ]->FamilyUid() == uid )
+ {
+ if ( aExecute )
+ {
+ iShutdownOperations[ count ]->Execute();
+ }
+ else
+ {
+ iShutdownOperations[ count ]->Cancel();
+ }
+ }
+ }
+ }