diff -r 67c6ff54ec25 -r a009639409f5 piprofiler/plugins/DiskWriterPlugin/src/DiskWriterPlugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/piprofiler/plugins/DiskWriterPlugin/src/DiskWriterPlugin.cpp Thu May 27 14:26:55 2010 +0300 @@ -0,0 +1,476 @@ +/* +* Copyright (c) 2009 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: +* +*/ + + +// Include Files + +#include "DiskWriterPlugin.h" // CDiskWriterPlugin +#include +#include +//#include + +// constants +const TUid KDiskWriterPluginUid = { 0x2001E5BB }; // own UID + +// engine properties +const TUid KEngineStatusPropertyCat={0x2001E5AD}; +enum TEnginePropertyKeys + { + EProfilerEngineStatus = 8, + EProfilerErrorStatus + }; + +/* + * + * Class CDiskWriterPlugin implementation + * + */ + +// Member Functions +CDiskWriterPlugin* CDiskWriterPlugin::NewL(const TUid /*aImplementationUid*/, TAny* /*aInitParams*/) + { + LOGTEXT(_L("CDiskWriterPlugin::NewL() - entry")); + CDiskWriterPlugin* self = new (ELeave) CDiskWriterPlugin(KDiskWriterPluginUid); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + LOGTEXT(_L("CDiskWriterPlugin::NewL() - exit")); + return self; + } + +CDiskWriterPlugin::CDiskWriterPlugin(const TUid aImplementationUid) : + iWriterType(aImplementationUid.iUid) + { + LOGTEXT(_L("CDiskWriterPlugin::CDiskWriterPlugin - entry")); + isEnabled = EFalse; + iWriterId = Id().iUid; + LOGTEXT(_L("CDiskWriterPlugin::CDiskWriterPlugin - exit")); + } + +CDiskWriterPlugin::~CDiskWriterPlugin() + { + LOGTEXT(_L("CDiskWriterPlugin::~CDiskWriterPlugin - entry")); + + iErrorStatus.Close(); + + if(iWriterHandler) + { + iWriterHandler->Cancel(); + delete iWriterHandler; + } + LOGTEXT(_L("CDiskWriterPlugin::~CDiskWriterPlugin - exit")); + } + +void CDiskWriterPlugin::ConstructL() + { + // second phase constructor, anything that may leave must be constructed here + LOGTEXT(_L("CDiskWriterPlugin::ConstructL() - entry")); + iWriterHandler = CDiskWriterHandler::NewL(this); + User::LeaveIfError(iErrorStatus.Attach(KEngineStatusPropertyCat, EProfilerErrorStatus)); + LOGTEXT(_L("CDiskWriterPlugin::ConstructL() - exit")); + } + +TUid CDiskWriterPlugin::Id() const + { + LOGSTRING2("CDiskWriterPlugin::Id():0x%X", KDiskWriterPluginUid.iUid ); + return KDiskWriterPluginUid; + } + +void CDiskWriterPlugin::GetWriterVersion(TDes* aDes) + { + _LIT(KDiskWriterVersion, "1.0.0"); + aDes->Append(KDiskWriterVersion); + } + +TInt CDiskWriterPlugin::Start() + { +// if(isEnabled) +// { +// TRAPD(err, iWriterHandler->StartL()); +// if( err != KErrNone) +// { +// LOGTEXT(_L("Could not start writer plugin")); +// return err; +// } +// } + return KErrNone; + } + +void CDiskWriterPlugin::Stop() + { + // stop writer handler normally + iWriterHandler->Stop(); + } + +TBool CDiskWriterPlugin::GetEnabled() + { + return isEnabled; + } + +TUint32 CDiskWriterPlugin::GetWriterType() + { + return iWriterType; + } + + +void CDiskWriterPlugin::SetValue( const TWriterPluginValueKeys aKey, + TDes& aValue ) + { + TRAP_IGNORE( SetValueL( aKey, aValue ) ); + } + + +void CDiskWriterPlugin::GetValue( const TWriterPluginValueKeys aKey, + TDes& aValue ) + { + TRAP_IGNORE( GetValueL( aKey, aValue ) ); + } + +void CDiskWriterPlugin::SetValueL( const TWriterPluginValueKeys aKey, TDes& aValue ) + { + TInt error(KErrNone); + + switch( aKey ) + { + case EWriterPluginEnabled: + isEnabled = ETrue; + LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - plugin enabled")); + break; + case EWriterPluginDisabled: + isEnabled = EFalse; + LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - plugin disabled")); + break; + case EWriterPluginSettings: // file name in case of disk writer plugin + iFileName.Zero(); + iFileName.Append(aValue); + error = iWriterHandler->TestFile(iFileName); + User::LeaveIfError(error); + break; + default: + break; + } + } + +void CDiskWriterPlugin::GetValueL( const TWriterPluginValueKeys aKey, TDes& aValue ) + { + switch( aKey ) + { + case EWriterPluginVersion: + GetWriterVersion(&aValue); + break; + case EWriterPluginType: + break; + case EWriterPluginSettings: // file name in disk writer case + aValue.Copy(iFileName); + default: + break; + } + } + +void CDiskWriterPlugin::DoCancel() + { + LOGTEXT(_L("CDebOutWriterPlugin::DoCancel - entry")); + } + +void CDiskWriterPlugin::WriteData() + { + // Activate handler to write data from buffer to output + LOGTEXT(_L("CDiskWriterPlugin::WriteData() - entry")); + TRAP_IGNORE(iWriterHandler->StartL()); + LOGTEXT(_L("CDiskWriterPlugin::WriteData() - exit")); + } + +void CDiskWriterPlugin::HandleError(TInt aError) + { + TInt err(KErrNone); + RDebug::Print(_L("CDiskWriterPlugin::HandleError() - error received: %d"), aError); + err = iErrorStatus.Set(aError); + if(err != KErrNone) + { + RDebug::Print(_L("CDiskWriterPlugin::HandleError() - error in updating property: %d"), err); + } + } + +/* + * + * Implementation of class CDiskWriterHandler + * + */ + +CDiskWriterHandler* CDiskWriterHandler::NewL(CDiskWriterPlugin* aWriter) + { + LOGTEXT(_L("CDiskWriterHandler::NewL() - entry")); + CDiskWriterHandler* self = new (ELeave) CDiskWriterHandler(aWriter); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + LOGTEXT(_L("CDiskWriterHandler::NewL() - exit")); + return self; + } + +CDiskWriterHandler::CDiskWriterHandler(CDiskWriterPlugin* aWriter) : + CActive(EPriorityStandard) + { + LOGTEXT(_L("CDiskWriterHandler::CDiskWriterHandler - entry")); + + iWriter = aWriter; + + // set initial mode to non-stopping + iStopping = EFalse; + + // add the handler to the active scheduler + CActiveScheduler::Add(this); + + LOGTEXT(_L("CDiskWriterHandler::CDiskWriterHandler - exit")); + } + + +CDiskWriterHandler::~CDiskWriterHandler() + { + LOGTEXT(_L("CDiskWriterHandler::~CDiskWriterHandler - entry")); + + LOGTEXT(_L("CDiskWriterHandler::~CDiskWriterHandler - exit")); + } + +void CDiskWriterHandler::ConstructL() + { + } + +TInt CDiskWriterHandler::TestFile(const TDesC& totalPrefix) + { + TParse parse; + + TInt err(KErrNone); + if((err = parse.Set(totalPrefix, NULL, NULL)) != KErrNone) + return err; + + err = iFs.Connect(); + if(err != KErrNone) + { + LOGTEXT(_L("CDiskWriterHandler::TestFile() - Failed to open a session to file server")); + return KErrNotFound; + } + + iFs.MkDirAll(parse.FullName()); + + err = iFile.Replace(iFs,parse.FullName(),EFileWrite); + if(err != KErrNone) + { + iFs.Close(); + return KErrNotFound; + } + + iFileName.Copy(parse.FullName()); + + return KErrNone; + } + +void CDiskWriterHandler::Reset() + { + // cancel active object + Cancel(); + + // start writing new buffer if there is one available + TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer(); + + // empty the rest of the buffers synchronously + while(nextBuf != 0) + { + LOGTEXT(_L("CDiskWriterHandler::Reset - writing to file")); + if(nextBuf->iDataSize != 0) + { + LOGTEXT(_L("CDiskWriterHandler::Reset - writing to file")); + WriteMemBufferToFile(*(nextBuf->iBufDes),iStatus); + } + + // empty buffers when profiling stopped + iWriter->iStream->AddToFreeBuffers(nextBuf); + + LOGTEXT(_L("CDiskWriterHandler::Reset - get next full buffer")); + // start writing new buffer if there is one available + nextBuf = iWriter->iStream->GetNextFilledBuffer(); + LOGSTRING2("CDiskWriterHandler::Reset - got next filled 0x%x",nextBuf); + } + } + +void CDiskWriterHandler::HandleFullBuffers() + { + LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - entry")); + // previous write operation has finished + // release the previous buffer + iWriter->iStream->AddToFreeBuffers(iBufferBeingWritten); + + LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - get next full buffer")); + // start writing new buffer if there is one available + TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer(); + + if(nextBuf != 0) + { + LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - writing to file")); + if(nextBuf->iDataSize != 0) + { + WriteBufferToOutput(nextBuf); + } + } + LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - exit")); + } + +void CDiskWriterHandler::RunL() + { + LOGTEXT(_L("CDiskWriterHandler::RunL - entry")); + // call function to complete full buffer handling + HandleFullBuffers(); + LOGTEXT(_L("CDiskWriterHandler::RunL - exit")); + } + +void CDiskWriterHandler::DoCancel() + { + + } + +//----------------------------------------------------------------------------- +// CPIProfilerTraceCoreLauncher::RunError(TInt aError) +// Handle leaves from RunL(). +//----------------------------------------------------------------------------- +TInt CDiskWriterHandler::RunError(TInt aError) + { + // no reason to continue if disk full or removed + iFile.Close(); + // close handle to file server too + iFs.Close(); + iFileName.Zero(); + + iWriter->HandleError(KErrDiskFull); + return aError; + } + +void CDiskWriterHandler::WriteMemBufferToFile(TDesC8& aDes, TRequestStatus& aStatus) + { + LOGTEXT(_L("CDiskWriterPlugin::WriteMemBufferToFile - entry")); + + TUint sampleSize(aDes.Length()); + TInt err(KErrNone); + TInt drive(0); + TDriveInfo info; + TBool noDiskSpace(EFalse); + + err = iFile.Drive(drive,info); + + // test available disk space + TRAP_IGNORE((noDiskSpace = SysUtil::DiskSpaceBelowCriticalLevelL(&iFs, sampleSize, drive))); + // check first if still space on disk + if(noDiskSpace) + { + // set error to disk full + err = KErrDiskFull; + LOGTEXT(_L("CDiskWriterPlugin::WriteMemBufferToFile - disk full, cannot write")); + } + else + { + // check if profiling in stopping mode + if(iStopping) + { + // RDebug::Print(_L("CDiskWriterPlugin::WriteMemBufferToFile - data written, length %d, stopping"), aDes.Length()); + // write to file without status + err = iFile.Write(aDes); + } + else + { + // RDebug::Print(_L("CDiskWriterPlugin::WriteMemBufferToFile - data written, length %d"), aDes.Length()); + // write to file with status + iFile.Write(aDes,aStatus); + } + } + + // check if error in write + if(err != KErrNone) + { + // stop writer handler (and its timer) immediately, DO NOT try write data! + Cancel(); + + // no reason to continue if disk full or removed + // end of stream detected, file can be closed + iFile.Close(); + // close handle to file server too + iFs.Close(); + iFileName.Zero(); + + // set error status for engine to read + iWriter->HandleError(err); + } + LOGTEXT(_L("CDiskWriterPlugin::WriteMemBufferToFile - exit")); + } + +void CDiskWriterHandler::WriteBufferToOutput(TBapBuf* aBuf) + { + LOGTEXT(_L("CDiskWriterPlugin::WriteBufferToOutput - entry")); + iBufferBeingWritten = aBuf; + + // set the data length just to be sure + iBufferBeingWritten->iBufDes->SetLength(aBuf->iDataSize); + + LOGTEXT(_L("CDiskWriterPlugin::WriteBufferToOutput - writing to file")); + WriteMemBufferToFile(*(iBufferBeingWritten->iBufDes), iStatus); + + // set AO back to active, until filled buffers are emptied + SetActive(); + + LOGTEXT(_L("CDiskWriterPlugin::WriteBufferToOutput - exit")); + } + +void CDiskWriterHandler::StartL() + { + LOGTEXT(_L("CDiskWriterHandler::StartL - entry")); + if(!IsActive()) + { + LOGTEXT(_L("CDiskWriterHandler::StartL - is not active")); + + TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer(); + LOGSTRING2("CDiskWriterHandler::StartL - got next filled 0x%x",nextBuf); + + if(nextBuf != 0) + { + LOGTEXT(_L("CDiskWriterHandler::StartL - writing to file")); + WriteBufferToOutput(nextBuf); + } + } + LOGTEXT(_L("CDiskWriterHandler::StartL - exit")); + } + +void CDiskWriterHandler::Stop() + { + LOGTEXT(_L("CDiskWriterHandler::Stop - entry")); + + // set to stopping mode, needed for emptying the remaining full buffers + iStopping = ETrue; + + // stop the timer + Reset(); + + // end of stream detected, file can be closed + iFile.Close(); + // close handle to file server too + iFs.Close(); + iFileName.Zero(); + + // set mode back to non-stopping + iStopping = EFalse; + + LOGTEXT(_L("CDiskWriterHandler::Stop - exit")); + } + +// end of file