Discussion Board

Results 1 to 3 of 3
  1. #1
    Registered User supaflyzzz's Avatar
    Join Date
    Aug 2008
    Posts
    2
    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:
    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());
    	}
    }
    CActive instance creation:
    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);
    }
    Destructor:
    Code:
    CMyAppUi::~CMyAppUi() {
    	if (iAppView) {
    		RemoveFromStack(iAppView);
    		delete iAppView;
    	}
    	delete iBuf;
    	delete req;	
    }
    Invoke:
    Code:
    void CMyAppUi::HandleCommandL(TInt aCommand) {
    ...
    		case EAbout:
    			req->makeRequest(iBuf, this);
    			break;
    ...
    }

  2. #2
    Nokia Developer Moderator wizard_hu_'s Avatar
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    27,744
    Check the value of your state variable, and if Reset goes to the branch you expect. Although the usual approach is Cancel-ing things in DoCancel, but Close-ing them after the Cancel returns in the destructor, your Reset method should be fine too.
    Where do you see your thread as alive, and how long? Does EikStart::RunApplication return?

  3. #3
    Registered User supaflyzzz's Avatar
    Join Date
    Aug 2008
    Posts
    2
    Quote Originally Posted by wizard_hu_ View Post
    Check the value of your state variable, and if Reset goes to the branch you expect. Although the usual approach is Cancel-ing things in DoCancel, but Close-ing them after the Cancel returns in the destructor, your Reset method should be fine too.
    Reset calls immediatly after fetching URL, with iState = 5 (EReceive), so code correctly closes all instances of iSocket, iResolver, iConn and iSockServ and sets iState = 0 (EIdle).


    Quote Originally Posted by wizard_hu_ View Post
    Where do you see your thread as alive, and how long? Does EikStart::RunApplication return?
    I'm using On-Device debug (because emulator is too slow for debugging).
    If i run debug session without running CActive, application shutdown correctly and EikStart::RunApplication is returns. But if during session i try to fetch url, by running CActive, after Exit() call, App TRK show's me "Welcome to TRK.. " but EikStart::RunApplication is not returns. On debug tab i see my process which has one active thread running.

    I wait some time (by drinking one cup of tea) but thread still running. Sad.

Similar Threads

  1. Replies: 3
    Last Post: 2008-06-03, 12:22
  2. RSocket in emulator...
    By FireStoke in forum Symbian Networking & Messaging (Closed)
    Replies: 24
    Last Post: 2005-11-11, 11:15

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Nokia Developer aims to help you create apps and publish them so you can connect with users around the world.

京ICP备05048969号  © Copyright Nokia 2013 All rights reserved