sl@0: // Copyright (c) 1997-2010 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: /** sl@0: @file sl@0: */ sl@0: sl@0: #include "FLOGSVR.H" sl@0: #include "FLOGMAN.H" sl@0: #include "FLOGSTD.H" sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: const TInt KOpenLogFilesGranularity=5; sl@0: sl@0: /* Internal error. Use positive number to ensure no conflict with other error code sl@0: Indicate that client message has panic'ed and should not be completed. sl@0: */ sl@0: const TInt KErrMessagePanic = 1; sl@0: sl@0: /** sl@0: panics for log client sl@0: sl@0: @internalComponent sl@0: */ sl@0: enum TLogClientPanic sl@0: { sl@0: ELogDirectoryNameDoesNotExist =1, ///< panic if no log directory name sl@0: ELogFileNameDoesNotExist ///< panic if file name doesnot exist sl@0: }; sl@0: sl@0: /** sl@0: CFileLoggerServer class definition sl@0: */ sl@0: sl@0: CFileLoggerServer* CFileLoggerServer::NewL() sl@0: /** sl@0: Creates new CFileLoggerServer object sl@0: sl@0: @return Pointer to CFileLoggerServer object sl@0: */ sl@0: { sl@0: sl@0: CFileLoggerServer* r=new(ELeave) CFileLoggerServer(); sl@0: CleanupStack::PushL(r); sl@0: r->ConstructL(); sl@0: r->StartL(KFLoggerServerName); sl@0: CleanupStack::Pop(); sl@0: return r; sl@0: } sl@0: sl@0: CFileLoggerServer::CFileLoggerServer() sl@0: : CServer2(EPriority) sl@0: {} sl@0: sl@0: void CFileLoggerServer::ConstructL() sl@0: { sl@0: sl@0: iLoggerManager=CFileLoggerManager::NewL(); sl@0: iSessionCounter=CFileLogSessionCounter::NewL(); sl@0: } sl@0: sl@0: CFileLoggerServer::~CFileLoggerServer() sl@0: /** sl@0: Destructor sl@0: */ sl@0: { sl@0: sl@0: delete iSessionCounter; sl@0: delete iLoggerManager; sl@0: } sl@0: sl@0: CFileLogSessionCounter* CFileLoggerServer::SessionCounter() const sl@0: { sl@0: sl@0: return iSessionCounter; sl@0: } sl@0: sl@0: void CFileLoggerServer::Error(TInt aError) sl@0: { sl@0: sl@0: Message().Complete(aError); sl@0: ReStart(); sl@0: } sl@0: sl@0: CSession2* CFileLoggerServer::NewSessionL(const TVersion &aVersion, const RMessage2& /* aMessage */) const sl@0: /** sl@0: Create a new server session. Check we're the right version and make a new session sl@0: sl@0: @param aVersion version of new session sl@0: */ sl@0: { sl@0: sl@0: TVersion v(KFLogSrvMajorVersionNumber,KFLogSrvMinorVersionNumber,KFLogSrvBuildVersionNumber); sl@0: if (!User::QueryVersionSupported(v,aVersion)) sl@0: User::Leave(KErrNotSupported); sl@0: sl@0: iSessionCounter->CancelTimer(); sl@0: return CFileLogSession::NewL(CONST_CAST(CFileLoggerServer*,this),iLoggerManager); sl@0: } sl@0: /** sl@0: CFileLogSessionCounter class definition sl@0: */ sl@0: sl@0: CFileLogSessionCounter* CFileLogSessionCounter::NewL() sl@0: /** sl@0: Creates new CFileLogSessionCounter object sl@0: sl@0: @return Pointer to CFileLogSessionCounter object sl@0: */ sl@0: { sl@0: sl@0: CFileLogSessionCounter* r=new(ELeave) CFileLogSessionCounter(); sl@0: CleanupStack::PushL(r); sl@0: r->ConstructL(); sl@0: CleanupStack::Pop(); sl@0: return r; sl@0: } sl@0: sl@0: CFileLogSessionCounter::~CFileLogSessionCounter() sl@0: /** sl@0: Destructor sl@0: */ sl@0: { sl@0: sl@0: delete iShutdownTimer; sl@0: } sl@0: sl@0: CFileLogSessionCounter::CFileLogSessionCounter() sl@0: : iSessionCount(0) sl@0: /** sl@0: Default Constructor sl@0: */ sl@0: {} sl@0: sl@0: void CFileLogSessionCounter::ConstructL() sl@0: { sl@0: sl@0: iShutdownTimer=CShutdownTimer::NewL(); sl@0: } sl@0: sl@0: void CFileLogSessionCounter::IncrementSessionCount() sl@0: /** sl@0: Increments the Session count sl@0: */ sl@0: { sl@0: sl@0: iSessionCount++; sl@0: } sl@0: sl@0: void CFileLogSessionCounter::DecrementSessionCount() sl@0: /** sl@0: Decrements the Session count sl@0: */ sl@0: { sl@0: sl@0: iSessionCount--; sl@0: if (iSessionCount<=0) sl@0: iShutdownTimer->After(KShutdownPause); sl@0: } sl@0: sl@0: void CFileLogSessionCounter::CancelTimer() sl@0: /** sl@0: Cancels the timer sl@0: */ sl@0: { sl@0: sl@0: iShutdownTimer->Cancel(); sl@0: } sl@0: sl@0: /** sl@0: CShutdownTimer class definitions sl@0: */ sl@0: sl@0: CShutdownTimer* CShutdownTimer::NewL() sl@0: /** sl@0: Creates new CShutdownTimer object sl@0: @return Pointer to CShutdownTimer object sl@0: */ sl@0: { sl@0: sl@0: CShutdownTimer* r=new(ELeave) CShutdownTimer(); sl@0: CleanupStack::PushL(r); sl@0: r->ConstructL(); sl@0: CleanupStack::Pop(); sl@0: return r; sl@0: } sl@0: sl@0: CShutdownTimer::~CShutdownTimer() sl@0: /** sl@0: Destructor sl@0: */ sl@0: {} sl@0: sl@0: CShutdownTimer::CShutdownTimer() sl@0: : CTimer(EPriorityIdle) sl@0: /** sl@0: Default Constructor sl@0: */ sl@0: { sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: void CShutdownTimer::RunL() sl@0: /** sl@0: */ sl@0: { sl@0: sl@0: CActiveScheduler::Stop(); sl@0: } sl@0: sl@0: /** sl@0: CFileLogSession class definition sl@0: */ sl@0: sl@0: CFileLogSession* CFileLogSession::NewL(CFileLoggerServer* aServer, CFileLoggerManager* aManager) sl@0: { sl@0: sl@0: CFileLogSession* r=new(ELeave) CFileLogSession(aServer,aManager); sl@0: CleanupStack::PushL(r); sl@0: r->ConstructL(); sl@0: CleanupStack::Pop(); sl@0: return r; sl@0: } sl@0: sl@0: CFileLogSession::CFileLogSession( CFileLoggerServer* aServer, CFileLoggerManager* aManager) sl@0: : CSession2(), iLoggerServer(aServer), iLoggerManager(aManager) sl@0: {} sl@0: sl@0: void CFileLogSession::ConstructL() sl@0: { sl@0: sl@0: iLoggerServer->SessionCounter()->IncrementSessionCount(); // should be done first because it will be decremented in the destructor sl@0: iOpenLogFiles=new(ELeave) CArrayFixFlat(KOpenLogFilesGranularity); sl@0: } sl@0: sl@0: CFileLogSession::~CFileLogSession() sl@0: /** sl@0: Destructor sl@0: */ sl@0: { sl@0: if (iOpenLogFiles) sl@0: { sl@0: TInt count=iOpenLogFiles->Count(); sl@0: TInt i; sl@0: for (i=0; iCloseLog(iOpenLogFiles->At(i)); sl@0: } sl@0: iOpenLogFiles->Delete(0,count); sl@0: delete iOpenLogFiles; sl@0: } sl@0: iLoggerServer->SessionCounter()->DecrementSessionCount(); // starts the timer if this is the last session sl@0: } sl@0: sl@0: void CFileLogSession::ServiceL(const RMessage2& aMessage) sl@0: /** sl@0: @internalTechnology sl@0: */ sl@0: { sl@0: sl@0: TRAPD(ret,DispatchMessageL(aMessage)); sl@0: if (ret!=KErrMessagePanic) sl@0: { sl@0: aMessage.Complete(ret); sl@0: } sl@0: } sl@0: sl@0: void CFileLogSession::DispatchMessageL(const RMessage2& aMessage) sl@0: { sl@0: sl@0: TInt func=aMessage.Function(); sl@0: if (func!=ECreateLog && func!=EWriteLog && func!=ECloseLog && func!=ECreateWriteAndCloseLog) sl@0: User::Leave(KErrNotSupported); sl@0: sl@0: TLogFile log; sl@0: TPckg logPckg(log); sl@0: aMessage.ReadL(0,logPckg); sl@0: if (log.Directory().Length()<=0) sl@0: { sl@0: aMessage.Panic(KFLoggerServerName,ELogDirectoryNameDoesNotExist); sl@0: User::Leave(KErrMessagePanic); sl@0: } sl@0: sl@0: if (log.Name().Length()<=0) sl@0: { sl@0: aMessage.Panic(KFLoggerServerName,ELogFileNameDoesNotExist); sl@0: User::Leave(KErrMessagePanic); sl@0: } sl@0: sl@0: // TBuf8 buf; sl@0: TBuf8<1600> buf; sl@0: if (func==EWriteLog || func==ECreateWriteAndCloseLog) sl@0: { sl@0: aMessage.ReadL(1,buf); sl@0: } sl@0: sl@0: switch (func) sl@0: { sl@0: case ECreateLog: sl@0: OpenLogL(log); sl@0: aMessage.WriteL(0,logPckg); sl@0: break; sl@0: sl@0: case EWriteLog: sl@0: iLoggerManager->WriteToLogL(log,buf); sl@0: break; sl@0: sl@0: case ECloseLog: sl@0: CloseLog(log); sl@0: break; sl@0: sl@0: case ECreateWriteAndCloseLog: sl@0: { sl@0: OpenLogL(log); // Ok to leave here; assume that log not left open sl@0: TInt rc = aMessage.Write(0,logPckg); sl@0: if (rc == KErrNone && log.Valid()) sl@0: TRAP(rc,iLoggerManager->WriteToLogL(log,buf)); sl@0: CloseLog(log); sl@0: User::LeaveIfError(rc); sl@0: break; sl@0: } sl@0: sl@0: default: sl@0: User::Leave(KErrNotSupported); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: sl@0: void CFileLogSession::OpenLogL(TLogFile& aLogFile) sl@0: /** sl@0: Opens log file sl@0: sl@0: @param aLogFile Log file name sl@0: */ sl@0: { sl@0: sl@0: iOpenLogFiles->AppendL(aLogFile); sl@0: iLoggerManager->FindOrCreateLogL(aLogFile); sl@0: } sl@0: sl@0: void CFileLogSession::CloseLog(TLogFile& aLogFile) sl@0: /** sl@0: Closes the log file sl@0: sl@0: @param aLogFile Log file name sl@0: */ sl@0: { sl@0: sl@0: iLoggerManager->CloseLog(aLogFile); sl@0: TInt count=iOpenLogFiles->Count(); sl@0: TInt i=0; sl@0: for (i=0; iAt(i)==aLogFile) sl@0: { sl@0: iOpenLogFiles->Delete(i,1); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: __ASSERT_DEBUG(i<=count, User::Invariant()); sl@0: } sl@0: