×

Discussion Board

Results 1 to 5 of 5
  1. #1
    Regular Contributor
    Join Date
    Mar 2007
    Posts
    235

    Question Is there any example for thread suspend and resume?

    I need to create one thread and suspend it time to time for data interchange between main process and thread and resume thread execution . Is there any good tutorial or any good code ?

  2. #2
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    28,684

    Re: Is there any example for thread suspend and resume?

    RThread actually have such methods (Suspend, Resume). However in practice threads are not suspended when they are communicating...
    What do you need exactly? You can check IPC examples in Examples\Base\IPC.

  3. #3
    Super Contributor
    Join Date
    Nov 2004
    Location
    Wiltshire, UK
    Posts
    3,644

    Re: Is there any example for thread suspend and resume?

    I would be very hard pressed to find a reason why you would pause and resume threads when you have the normal synchronization primatives such a critical sections, mutexes and semaphores avaliable to handle cross thread updates such as adding to an array for example
    Download Symbian OS now! [url]http://developer.symbian.org[/url]

  4. #4
    Regular Contributor
    Join Date
    Mar 2007
    Posts
    235

    Question Re: Is there any example for thread suspend and resume?

    I am initialising a thread for Url data fetching and passing this data stucture to it .
    Code:
    class CThreadData : public CBase
    {
    public:
    	virtual ~CThreadData();
    	static CThreadData* NewL();
    	static CThreadData* NewLC();
    private:
    	CThreadData();
    	void ConstructL();
    public:
       RArray<TInt>	&	 	StateData(); //should be initilised by the main process and passed to thread
       CDesCArray* 			ThreadData();
    // Parsed fetched data returned by thread .
       RFileLogger &		LogFile();
    //used by both main process and thread for data logging   TBuf<25> 			iStatusText;
       TPtrC 			iScreenText;
       TSize 			iImageSize;   
       TUint32			iIap;
       TInt                         iCharWidth;//value initialised by main process used in thread
       TInt				iSizeCol0;
        TInt			iSizeCol1;
        TInt 			iSizeCol2;
        TInt			iSizeCol3;
        TInt 			iSizeCol4;
        TInt			iSizeCol5;
    //values initialised in thread used in main   TBuf<90>			iwriteBuf;
       TBuf<25>			iStr;
       RArray<TIap>			iIAPs;
       TInt                         iTotNumberofRows;
    private:
        RFileLogger 		iLog;
        RArray<TInt> 		iStateData;
        CDesCArray* 		iThreadData;
    	
    };
    Code:
    _LIT(KExecThreadBaseName, "CPortThread");
     
    // Global thread id counter for making CPortThread thread names unique.
    // This is achieved by appending counter to the end of thread name and
    // incrementing counter value for next thread.
    // This is writable static data.
    
     
    LOCAL_C void GenerateUniqueName(TDes& aResult, CPortThread* aExecutor,TInt g_thread_id_counter)
        {
        _LIT(KHexFormat, "_0x%x");
        _LIT(KCounterFormat, "_%d");
        aResult.Copy(KExecThreadBaseName);
        aResult.AppendFormat(KHexFormat, aExecutor);
        g_thread_id_counter++;
        aResult.AppendFormat(KCounterFormat, g_thread_id_counter);
        }
     
    CPortThread* CPortThread::NewL(/*MThreadExecuteObserver*/CAknExGridAppUi* aObserver)
        {
        CPortThread* self = new (ELeave) CPortThread(aObserver);
        CleanupStack::PushL(self);
        self->ConstructL();
        CleanupStack::Pop(self);    
        return self;
        }
     
    CPortThread::CPortThread(CAknExGridAppUi/*MThreadExecuteObserver*/* aObserver)
        : CActive(EPriorityHigh),iAppUi(aObserver),iObserver((MThreadExecuteObserver&)*aObserver)
        //, idatapuller(NULL), iEngine(NULL)
        {
        KStackSize = 16384;
        KHeapMinSize =1000;
        KHeapSize = 16384;
        CActiveScheduler::Add(this);
        }
     
    CPortThread::~CPortThread()
        {
        Cancel();
        iThread.Close();
        }
     
    void CPortThread::ConstructL()
        {
    //    iHttpThreadCreated=EFalse;
        }
     
    TInt CPortThread::ExecuteThread(/*TTimeIntervalMicroSeconds32 anInterval*/)
        {
        TInt ret = KErrNone;
    //    iInterval = anInterval;
        TRAP(ret,CreateThreadL());
        if (!ret)
            {
             ret = StartThread();
            }
        return ret;
        }
     
    TInt CPortThread::StartThread()
        {
        TInt ret = KErrNone;
        if(!IsActive())
            {
            SetActive();
            }
        else
            {
            ret = KErrOverflow;
            }
        return ret;
        }
     
    void CPortThread::ThreadExecuted(TInt aError)
        {
        iObserver.ThreadExecuted(aError);
        }
     
    void CPortThread::RunL()/// thread state handler
        {
        TInt val=iAppUi->iThreaddata->StateData().operator[](17);
        switch(iAppUi->iThreaddata->StateData().operator[](17))
        {
        case CThreadData::KStateInitState:
        break;
        case CThreadData::KDataEnteringThread:
        iThread.Logon(iStatus);
        iThread.Resume();
        break;
        case CThreadData::KDataInitState:
        break;
        case CThreadData::KDataExitingThread: //used on suspension
        iObserver.ThreadExecuted(iStatus.Int());
        break;
        case CThreadData::KDataProcessingState:    
        break;
        case CThreadData::KDataError:
        break;
        
        }
        }
     
    void CPortThread::DoCancel()
        {
        iThread.LogonCancel(iStatus);
        iThread.Kill(KErrCancel);
        }
     
    void CPortThread::CreateThreadL()
        {
        HBufC* threadName = HBufC::NewLC(KMaxFileName);
        TPtr ptr = threadName->Des();
        GenerateUniqueName(ptr, this,g_thread_id_counter); 
        User::LeaveIfError(iThread.Create(
                            *threadName,
                            CPortThread::ThreadFunction,
                            KStackSize,
                            KHeapMinSize,
                            KHeapSize,
                            this
                            /*,EOwnerProcess*/
                           ));
      
        CleanupStack::PopAndDestroy(threadName);
        }
    void CPortThread::InitThread (CAknExGridAppUi* aAppUi)
    	{	
    	// 3. Add support for active objects
    	CActiveScheduler* iactiveScheduler = new (ELeave) CActiveScheduler;
        CleanupStack::PushL(iactiveScheduler);
        CActiveScheduler::Install(iactiveScheduler);
         // Create Engine Object
        CThreadData &data=*aAppUi->iThreaddata;
        CPortThread &thread=*aAppUi->iHttpThread;
        CDataPuller * datapuller=new (ELeave)CDataPuller(thread,data);
    //    datapuller->ConstructL(aAppUi->iThreaddata);
        CPMHttpEngine* Engine= CPMHttpEngine::NewL(data);//Active class    ////    // 5. --> Thread execution starts
        CActiveScheduler::Start();
        Engine->SetTransactionObserver(datapuller);
        Engine->SetActivateL();
        Engine->DoCancel();
        CActiveScheduler::Stop();
    //    // 6. --> Thread execution ends (waiting for CActiveScheduler::Stop())
    //
    //    CleanupStack::PopAndDestroy(Engine);
        CleanupStack::PopAndDestroy(iactiveScheduler);
    	}
    //Cportthread
    TInt CPortThread::ThreadFunction(TAny* aParams)
        {
        // 1. Add cleanup stack support.
        CTrapCleanup* cleanupStack = CTrapCleanup::New();
         
            // 2. Get pointer to thread host
    //    CPortThread* host = (CPortThread*)aParams;
        CAknExGridAppUi* AppUi=(CAknExGridAppUi*)aParams;
        //3. TAny Object
       
            TRAPD(err,
            		InitThread (AppUi);
                );
            AppUi->iStr2.Format(_L("Error%5D"),err);
            AppUi->iThreaddata->LogFile().Write(AppUi->iStr2);
            TInt errcd=err;
            delete cleanupStack;
            return KErrNone;
        }
     // End of File
    I was just suspending the thread to call above host class's RunL
    with
    Code:
    iThread.iThread.Suspend();
    iThread.StartThread();
    return ETrue;
    which would finally decide which process is executing just now , a little bit control over the thread .
    The problem I am facing is the emualator I am getting
    Code:
    void CPMHttpEngine::ConstructL(/*CThreadData* aThreadData*/)
    	{
       CActiveScheduler::Add(this);
    //	iThreadData=aThreadData;
    	User::LeaveIfError(iSockServ.Connect());
    	User::LeaveIfError(iConnection.Open(iSockServ));
    	iConnOpener = CPMConnectionOpener::NewL(iConnection,*this);
    
    	TRAPD(err,iMsvSession = CMsvSession::OpenAsyncL(*this);)//emulator exiting 
    at this line . There was no problem when this
    code was running on main thread and forground :(         iThreadData.iStr.Num(err);
    	iThreadData.LogFile().Write(iThreadData.iStr);#ifndef __WINS__
    	iServer.Copy(KUrlServerALive);
    #else
    	iServer.Copy(KUrlServerMOfffice);
    #endif
    	iPhone.Copy(KSimAirtel);
    	// open RHTTPSession with default protocol ("HTTP/TCP")
    	iHttpSession.OpenL();
    	iFlagsetIap =EFalse;
    	
    	LoadIapsL();
    	
    	// no IAPs defined in the device.
    	if (iIAPs.Count() == 0)
    		{
    		CEikonEnv::Static()->LeaveWithInfoMsg(R_PM_NO_IAPS_DEFINED);
    		}
    	
    //	TTimeIntervalMicroSeconds32 Start=0;
    //	TTimeIntervalMicroSeconds32 Interval=11*10000;
    //	iPeriodicConnection->Start(Start,Interval,TCallBack(Period, this));
    	}
    Last edited by gigglie; 2008-06-25 at 12:59.

  5. #5
    Super Contributor
    Join Date
    Nov 2004
    Location
    Wiltshire, UK
    Posts
    3,644

    Re: Is there any example for thread suspend and resume?

    Just like the answer to the question "Would'nt it be a good idea if..." is always no, so the answer to "Should I use a thread to... " is always no.
    As the thread is for the most part always waiting for an AO to be signalled and there are outstanding requests signalled I have no doubt there are problems suspending the thread this way. Normally in Symbian the engine is split into a seperate process and you use Symbian's IPC to handle the load between the two processes which works out much more efficiently.

    However Typical usage patterns involve sharing a critical section between threads when updating any data. Lets say you have an RArray to share between two threads. If you need to read or write to the thread you wait until you get access and then do what you need to..

    iCriticalSection.Wait();
    iGlobalArray.Append(_L("Something");
    iCriticalSection.Exit();

    Sharing the RArray (and for that matter any shared object larger than 32 bits on a single core processor) as you have there is a recipe for wierd kern exec 3 errors.

    Some ideas why you are getting crashes:
    1. Two threads reading and writing over the same block of memory. Looking at the code I spotted 4 instances where there are potential issues.
    2. Reading or writing to the UI (eg CCoeEnv::Static()->FsSession() is a big no) in the non primary thread
    3. There could be a problem the callback function (your implemenbtation of the obeserver) of the OpenAsyncL method
    4. What is the actual error message? (Enable extended error codes as documented in the wiki)

    http://en.wikipedia.org/wiki/Synchro...puter_science)
    Last edited by ltomuta; 2008-06-25 at 16:32. Reason: Fixed wikipedia link
    Download Symbian OS now! [url]http://developer.symbian.org[/url]

Similar Threads

  1. Replies: 1
    Last Post: 2006-03-08, 04:41
  2. How can I test Suspend / Resume functionality on Emulator?
    By m_surenderreddy in forum Mobile Java General
    Replies: 0
    Last Post: 2003-11-25, 11:08

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×