×
Namespaces

Variants
Actions

Archived:RThread - Symbian threading example

From Nokia Developer Wiki
Jump to: navigation, search

Archived.pngArchived: This article is archived because it is not considered relevant for third-party developers creating commercial solutions today. If you think this article is still relevant, let us know by adding the template {{ReviewForRemovalFromArchive|user=~~~~|write your reason here}}.

The content is still valid (to at least Nokia Belle), but is better covered by the Fibonacci1-3: asynchronous programming with active objects examples in the SDK.

Article Metadata
Tested with
Devices(s): Nokia N95
Compatibility
Platform(s): S60 3rd Edition FP1 and later
Symbian
Nokia Belle
Symbian Anna
Symbian^3
S60 5th Edition
Article
Keywords: RThread, CTrapCleanup, CActiveScheduler, CPeriodic
Created: tepaa (20 Mar 2008)
Last edited: hamishwillee (18 Sep 2012)

Contents

Overview

This RThread example shows how to:

  • Create a simple CMyThread thread class that runs RThread
  • How to listen for thread execution
  • How add cleanup stack support for threads
  • How add active scheduler support for threads


The CMyThread thread runs the CPeriodic timer.

MMP file

RThread needs

LIBRARY euser.lib

Header

#include <e32base.h>
 
class MThreadExecuteObserver
{
public:
virtual void ThreadExecuted(TInt aError) = 0;
};
 
class CMyThread : public CActive, public MThreadExecuteObserver
{
public:
static CMyThread* NewL(MThreadExecuteObserver& aObserver);
virtual ~CMyThread();
TInt ExecuteThread(TTimeIntervalMicroSeconds32 anInterval);
inline TTimeIntervalMicroSeconds32 Interval(){return iInterval;};
 
private: // From MThreadExecuteObserver
void ThreadExecuted(TInt aError);
 
private: // From CActive
void RunL();
void DoCancel();
 
private:
CMyThread(MThreadExecuteObserver& aObserver);
void ConstructL();
void CreateThreadL();
TInt StartThread();
static TInt ThreadFunction(TAny* aParams);
static TInt PeriodicTick(TAny* aObject);
 
private:
MThreadExecuteObserver& iObserver;
RThread iThread;
TTimeIntervalMicroSeconds32 iInterval;
};

Source

#include "CMyThread.h"
 
const TInt KStackSize = 16384;
_LIT(KExecThreadBaseName, "CMyThread");
 
// Global thread id counter for making CMyThread 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.
TInt g_thread_id_counter = 0;
 
LOCAL_C void GenerateUniqueName(TDes& aResult, CMyThread* aExecutor)
{
_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);
}
 
CMyThread* CMyThread::NewL(MThreadExecuteObserver& aObserver)
{
CMyThread* self = new (ELeave) CMyThread(aObserver);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
 
CMyThread::CMyThread(MThreadExecuteObserver& aObserver)
: CActive(EPriorityStandard),iObserver(aObserver)
{
CActiveScheduler::Add(this);
}
 
CMyThread::~CMyThread()
{
Cancel();
iThread.Close();
}
 
void CMyThread::ConstructL()
{
}
 
TInt CMyThread::ExecuteThread(TTimeIntervalMicroSeconds32 anInterval)
{
TInt ret = KErrNone;
iInterval = anInterval;
TRAP(ret,CreateThreadL());
if (!ret)
{
ret = StartThread();
}
return ret;
}
 
TInt CMyThread::StartThread()
{
TInt ret = KErrNone;
if(!IsActive())
{
// Requests notification when this thread dies
// normally or otherwise
iThread.Logon(iStatus);
SetActive();
iThread.Resume();
}
else
{
ret = KErrOverflow;
}
return ret;
}
 
void CMyThread::ThreadExecuted(TInt aError)
{
iObserver.ThreadExecuted(aError);
}
 
void CMyThread::RunL()
{
iObserver.ThreadExecuted(iStatus.Int());
}
 
void CMyThread::DoCancel()
{
iThread.LogonCancel(iStatus);
iThread.Kill(KErrCancel);
}
 
void CMyThread::CreateThreadL()
{
HBufC* threadName = HBufC::NewLC(KMaxFileName);
TPtr ptr = threadName->Des();
GenerateUniqueName(ptr, this);
 
User::LeaveIfError(iThread.Create(
*threadName,
CMyThread::ThreadFunction,
KStackSize,
NULL,
this));
 
CleanupStack::PopAndDestroy(threadName);
}
 
TInt CMyThread::ThreadFunction(TAny* aParams)
{
// 1. Add cleanup stack support.
CTrapCleanup* cleanupStack = CTrapCleanup::New();
 
// 2. Get pointer to thread host
CMyThread* host = (CMyThread*)aParams;
 
TRAPD(err,
// 3. Add support for active objects
CActiveScheduler* activeScheduler = new (ELeave) CActiveScheduler;
CleanupStack::PushL(activeScheduler);
CActiveScheduler::Install(activeScheduler);
 
// 4. Create and start CPeriodic class that is executed in this thread
CPeriodic* periodic = CPeriodic::NewL(CActive::EPriorityLow);
CleanupStack::PushL(periodic);
periodic->Start(host->Interval(),host->Interval(),
TCallBack(host->PeriodicTick, host));
 
// NOTE: When adding CActiveScheduler support for threads we have to
// add atleast one active object in it or it fails on
// CActiveScheduler::Start().
// CPeriodic is derived from CActive active object so that is good for
// this example.
 
// 5. --> Thread execution starts
CActiveScheduler::Start();
// 6. --> Thread execution ends (waiting for CActiveScheduler::Stop())
 
CleanupStack::PopAndDestroy(periodic);
CleanupStack::PopAndDestroy(activeScheduler);
);
 
host->ThreadExecuted(err);
delete cleanupStack;
return KErrNone;
}
 
TInt CMyThread::PeriodicTick(TAny* aObject)
{
CMyThread* mythread = (CMyThread*)aObject;
if (mythread)
{
// Thread is executed once so time to stop it
CActiveScheduler::Stop();
// After this execution continues from CActiveScheduler::Start()
}
// Does not continue again
// Note: Does not work with this CPeriodic class
return EFalse;
}

Running the CMyThread

Place CMyThread into class member variable and execute it

TTimeIntervalMicroSeconds32 time(100);
iMyThread = CMyThread::NewL(*this);
iMyThread->ExecuteThread(time);

When the thread is executed and it calls its observer that is a reference parameter in CMyThread::NewL(*this)

void CYourClass::ThreadExecuted(TInt aError)
{
// Will be called after thread execution
}

Postconditions

The thread has been created and executed.

Version Hint

Windows Phone: [[Category:Windows Phone]]
[[Category:Windows Phone 7.5]]
[[Category:Windows Phone 8]]

Nokia Asha: [[Category:Nokia Asha]]
[[Category:Nokia Asha Platform 1.0]]

Series 40: [[Category:Series 40]]
[[Category:Series 40 1st Edition]] [[Category:Series 40 2nd Edition]]
[[Category:Series 40 3rd Edition (initial release)]] [[Category:Series 40 3rd Edition FP1]] [[Category:Series 40 3rd Edition FP2]]
[[Category:Series 40 5th Edition (initial release)]] [[Category:Series 40 5th Edition FP1]]
[[Category:Series 40 6th Edition (initial release)]] [[Category:Series 40 6th Edition FP1]] [[Category:Series 40 Developer Platform 1.0]] [[Category:Series 40 Developer Platform 1.1]] [[Category:Series 40 Developer Platform 2.0]]

Symbian: [[Category:Symbian]]
[[Category:S60 1st Edition]] [[Category:S60 2nd Edition (initial release)]] [[Category:S60 2nd Edition FP1]] [[Category:S60 2nd Edition FP2]] [[Category:S60 2nd Edition FP3]]
[[Category:S60 3rd Edition (initial release)]] [[Category:S60 3rd Edition FP1]] [[Category:S60 3rd Edition FP2]]
[[Category:S60 5th Edition]]
[[Category:Symbian^3]] [[Category:Symbian Anna]] [[Category:Nokia Belle]]

This page was last modified on 18 September 2012, at 05:34.
78 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×