First cut of thread pools in fshell. Not fully working yet.
Removed 4 overloads of CCommandBase::RunCommand[L] that are no longer used at all, and changed one more to not be exported as it's only used internally to iocli.dll.
Added a thread pool (CThreadPool) to fshell so that thread commands no longer have to spawn a new thread every time they run. As part of this, CCommandWrapperBase now derives from CActive so that CThreadCommand can use its CActive-ness. CThreadCommand rejigged quite a bit to use CThreadPool (via MTaskRunner interface).
// nitz.cpp// // Copyright (c) 2009 - 2010 Accenture. All rights reserved.// This component and the accompanying materials are made available// under the terms of the "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:// Accenture - Initial contribution//#include <fshell/ioutils.h>#include <etelmm.h>#include <commsdattypesv1_1.h>#include <cdblen.h>using namespace IoUtils;class CCmdNitz : public CCommandBase {public: static CCommandBase* NewLC(); ~CCmdNitz();private: CCmdNitz(); void OpenPhoneL(); void PrintNitzData(); void QueueNotification();private: // From CCommandBase. virtual const TDesC& Name() const; virtual void DoRunL(); virtual void OptionsL(RCommandOptionList& aOptions);private: // From CActive. virtual void RunL(); virtual void DoCancel();private: RTelServer iEtelServer; RMobilePhone iPhone; RMobilePhone::TMobilePhoneNITZ iNitzData; TBool iFollow; HBufC* iTsyName; TBool iFirstPrint; };CCommandBase* CCmdNitz::NewLC() { CCmdNitz* self = new(ELeave) CCmdNitz(); CleanupStack::PushL(self); self->BaseConstructL(); return self; }CCmdNitz::~CCmdNitz() { delete iTsyName; iPhone.Close(); iEtelServer.Close(); }CCmdNitz::CCmdNitz() : iFirstPrint(ETrue) { }const TDesC& CCmdNitz::Name() const { _LIT(KName, "nitz"); return KName; }void CCmdNitz::DoRunL() { OpenPhoneL(); TInt err = iPhone.GetNITZInfo(iNitzData); if (err == KErrNone) { PrintNitzData(); } else if (!iFollow) { LeaveIfErr(err, _L("Unable to get NITZ information")); } if (iFollow) { QueueNotification(); } }void CCmdNitz::RunL() { if (iStatus.Int() == KErrNone) { PrintNitzData(); QueueNotification(); } else { Complete(iStatus.Int()); } }void CCmdNitz::DoCancel() { }void CCmdNitz::OpenPhoneL() { if (iTsyName == NULL) { CommsDat::CMDBSession* db = CommsDat::CMDBSession::NewLC(KCDLatestVersion); CommsDat::CMDBField<TUint32>* globalSettingField = new(ELeave) CommsDat::CMDBField<TUint32>(CommsDat::KCDTIdModemPhoneServicesSMS); CleanupStack::PushL(globalSettingField); globalSettingField->SetRecordId(1); globalSettingField->LoadL(*db); TUint32 modemId = *globalSettingField; CommsDat::CMDBField<TDesC>* tsyField = new(ELeave) CommsDat::CMDBField<TDesC>(CommsDat::KCDTIdTsyName); CleanupStack::PushL(tsyField); tsyField->SetRecordId(modemId); TRAPL(tsyField->LoadL(*db), _L("Unable to read default TSY name")); TBuf<KCommsDbSvrMaxFieldLength> tsyName; tsyName = *tsyField; iTsyName = tsyName.AllocL(); CleanupStack::PopAndDestroy(3, db); // db, tsyField & globalSettingField } LeaveIfErr(iEtelServer.Connect(), _L("Unable to connect to the ETel server")); LeaveIfErr(iEtelServer.LoadPhoneModule(*iTsyName), _L("Unable to load TSY module \"%S\""), iTsyName); TInt numPhones = 0; LeaveIfErr(iEtelServer.EnumeratePhones(numPhones), _L("Couldn't enumerate phones")); TBool matchFound(EFalse); TInt phoneIndex; for (phoneIndex = 0; phoneIndex < numPhones; ++phoneIndex) { TName thisTsyName; if ((iEtelServer.GetTsyName(phoneIndex, thisTsyName) == KErrNone) && (iTsyName->CompareF(thisTsyName) == KErrNone)) { matchFound = ETrue; break; } } if (!matchFound) { LeaveIfErr(KErrNotFound, _L("Couldn't find phone using TSY \"%S\""), iTsyName); } RTelServer::TPhoneInfo phoneInfo; LeaveIfErr(iEtelServer.GetPhoneInfo(phoneIndex, phoneInfo), _L("Couldn't get phone info")); LeaveIfErr(iPhone.Open(iEtelServer, phoneInfo.iName), _L("Couldn't open phone")); }void CCmdNitz::PrintNitzData() { if (iFirstPrint) { iFirstPrint = EFalse; } else { Write(_L("\r\n")); } if (iNitzData.iNitzFieldsUsed & RMobilePhone::KCapsTimeAvailable) { Printf(_L("Universal time: %02d/%02d/%04d %02d:%02d:%02d.%d\r\n"), iNitzData.Day(), iNitzData.Month() + 1, iNitzData.Year(), iNitzData.Hour(), iNitzData.Minute(), iNitzData.Second(), iNitzData.MicroSecond()); } if (iNitzData.iNitzFieldsUsed & RMobilePhone::KCapsTimezoneAvailable) { Printf(_L("Time zone: %d (+/- 15 minute offsets from GMT)\r\n"), iNitzData.iTimeZone); } if (iNitzData.iNitzFieldsUsed & RMobilePhone::KCapsDSTAvailable) { Printf(_L("Daylight saving adjustment: %d (hours)\r\n"), iNitzData.iDST); } if (iNitzData.iNitzFieldsUsed & RMobilePhone::KCapsShortNameAvailable) { Printf(_L("Short network name: \"%S\"\r\n"), &iNitzData.iShortNetworkId); } if (iNitzData.iNitzFieldsUsed & RMobilePhone::KCapsLongNameAvailable) { Printf(_L("Long network name: \"%S\"\r\n"), &iNitzData.iLongNetworkId); } }void CCmdNitz::QueueNotification() { iPhone.NotifyNITZInfoChange(iStatus, iNitzData); SetActive(); }void CCmdNitz::OptionsL(RCommandOptionList& aOptions) { _LIT(KOptFollow, "follow"); aOptions.AppendBoolL(iFollow, KOptFollow); _LIT(KOptTsyName, "tsy-name"); aOptions.AppendStringL(iTsyName, KOptTsyName); }EXE_BOILER_PLATE(CCmdNitz)