Hi!
Strange situation. CActive object works ok, but after Exit() call i saw the thread is still running, like zombie process.
I thinks problem in Active Object cancel implementation. Can you help, what's wrong there?
My code:
CActive instance creation:Code:#include <textresolver.h> #include <eikenv.h> #include "HttpRequest.h" CHttpRequest::CHttpRequest(): CActive(EPriorityStandard) { } CHttpRequest* CHttpRequest::NewLC() { CHttpRequest* self = new (ELeave) CHttpRequest(); CleanupStack::PushL(self); self->ConstructL(); return self; } CHttpRequest* CHttpRequest::NewL() { CHttpRequest* self = CHttpRequest::NewLC(); CleanupStack::Pop(); // self; return self; } void CHttpRequest::ConstructL() { CActiveScheduler::Add(this); // Add to scheduler } CHttpRequest::~CHttpRequest() { Cancel(); } void CHttpRequest::DoCancel() { Reset(); } TInt CHttpRequest::RunError(TInt aError) { CTextResolver *iTextResolver = CTextResolver::NewLC(); _LIT(KHeaderText, "ERROR"); TPtrC title(KHeaderText); CEikonEnv::Static()->InfoWinL(title, iTextResolver->ResolveErrorString(aError)); delete iTextResolver; Reset(); return aError; } void CHttpRequest::Reset() { switch ( iState ) { case EReceive: case ESend: iSocket.CancelAll(); iSocket.Close(); case EConnecting: iResolver.Cancel(); iResolver.Close(); case EResolving: iConn.Close(); case EInitConnection: iSockServ.Close(); case EIdle: break; } iState = EIdle; } void CHttpRequest::makeRequest(CBufBase *anBuffer, CHttpRequestObserver *anObserver) { iState = EInitConnection; iOutBuffer = anBuffer; iObserver = anObserver; iSockServ.Connect(); SetActive(); } void CHttpRequest::InitConnection() { iState = EResolving; aPrefs.SetDialogPreference(ECommDbDialogPrefPrompt); aPrefs.SetDirection(ECommDbConnectionDirectionOutgoing); iConn.Open(iSockServ); iConn.Start(aPrefs, iStatus); SetActive(); } void CHttpRequest::ResolveHost() { iState = EConnecting; _LIT(KHostName, "host.com"); iResolver.Open(iSockServ, KAfInet, KProtocolInetTcp, iConn); iResolver.GetByName(KHostName, tName, iStatus); SetActive(); } void CHttpRequest::Connect() { iState = ESend; iAddr = tName().iAddr; iAddr.SetPort(80); iSocket.Open(iSockServ, KAfInet, KSockStream, KProtocolInetTcp, iConn); iSocket.Connect(iAddr, iStatus); SetActive(); } void CHttpRequest::Send() { iState = EReceive; iSocket.Write(_L8("GET / HTTP/1.0\r\nHost: host.com\r\n\r\n"), iStatus); SetActive(); } void CHttpRequest::Receive(TBool bContinue) { iState = EReceive; iOutBuffer->InsertL(iOutBuffer->Size(), iNetBuffer); iNetBuffer.Zero(); if ( bContinue ) { iSocket.RecvOneOrMore(iNetBuffer, 0, iStatus, iDummy); SetActive(); } } void CHttpRequest::RunL() { if ( iStatus.Int() == KErrNone || iStatus.Int() == KErrEof ) { switch ( iState ) { case EInitConnection: InitConnection(); iObserver->ToState(EInitConnection); break; case EResolving: ResolveHost(); iObserver->ToState(EResolving); break; case EConnecting: Connect(); iObserver->ToState(EConnecting); break; case ESend: Send(); iObserver->ToState(ESend); break; case EReceive: switch ( iStatus.Int() ) { case KErrNone: Receive(ETrue); iObserver->ToState(EReceive); break; case KErrEof: Receive(EFalse); iObserver->Fetched(); // successfully Reset(); break; } break; } } else { iObserver->Canceled(); Reset(); User::LeaveIfError(iStatus.Int()); } }
Destructor:Code:void CMyAppUi::ConstructL() { // Initialise app UI with standard value. BaseConstructL(CAknAppUi::EAknEnableSkin); iBuf = CBufFlat::NewL(256); // buffer for CHttpRequest req = CHttpRequest::NewL(); // iAppView = CMyAppView::NewL(ClientRect()); // Create view object AddToStackL(iAppView); }
Invoke:Code:CMyAppUi::~CMyAppUi() { if (iAppView) { RemoveFromStack(iAppView); delete iAppView; } delete iBuf; delete req; }
Code:void CMyAppUi::HandleCommandL(TInt aCommand) { ... case EAbout: req->makeRequest(iBuf, this); break; ... }




