Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Symbian OS Explained - Effective C++ Programming For Smartphones (2005) [eng].pdf
Скачиваний:
60
Добавлен:
16.08.2013
Размер:
2.62 Mб
Скачать

COMMON MISTAKES

149

handler of the CPeriodic object, which in turn calls its task-processing callback function. Thus, the callback may not be as exactly regular as the periodic value passed to the Start() request. If the timer completes but other, higher-priority, active objects have completed events, they are processed first. Alternatively, the RunL() method of another active object may be running when the timer elapses and a running active object cannot be pre-empted even if it has a lower priority than the CPeriodic object.

The response of signal and callback processing can be improved by ensuring that all active objects in the thread perform short, efficient RunL() methods and that the CPeriodic object has a higher priority than other active objects.

9.14 Common Mistakes

I’ve described the dos and don’ts of active objects fairly comprehensively in this chapter and the previous one. The most commonly encountered problem when writing active object code is the infamous ”stray signal” panic (E32USER-CBASE 46), which occurs when the active scheduler receives a completion event but cannot find an active object to handle it (i.e. one which is currently active and has a completed iStatus result, indicated by a value other than KRequestPending). Stray signals can arise for the following reasons:

CActiveScheduler::Add()was not called when the active object was constructed

SetActive() was not called following the submission of a request to the asynchronous service provider

the asynchronous service provider completed the TRequestStatus of an active object more than once – either because of a programming error in the asynchronous service provider (for example, when an already-completed request is cancelled) or because more than one request was submitted simultaneously on the same active object.

If a stray signal occurs from one of your active objects, it is worth checking against each of these.

Over the course of Chapters 8 and 9, I have described the cooperative multitasking nature of active objects, which means that an active object’s RunL() event handler cannot be pre-empted by any other in that thread, except by using nested active scheduler loops, which are strongly discouraged. In consequence, when using active objects for event handling in, for example, a UI thread, their event-handler methods must be kept short to keep the UI responsive.

150

ACTIVE OBJECTS UNDER THE HOOD

No active object should have a monopoly on the active scheduler that prevents other active objects from handling events. Active objects should be ”cooperative”. This means you should guard against:

writing lengthy RunL() or DoCancel() methods

repeatedly resubmitting requests

assigning your active objects a higher priority than is necessary.

Stray signals can arise if:

the active object is not added to the active scheduler

SetActive() is not called following the submission of a request

the active object is completed more than once for any given request.

9.15Summary

While the previous chapter gave a high-level overview of active objects on Symbian OS, this chapter focused on active objects in detail, walking through the roles, responsibilities and interactions between the active scheduler, active objects and the asynchronous service providers they encapsulate.

It contained the detail necessary to write good active object or asynchronous service provider code and to extend the active scheduler. Example code illustrated the use of active objects for state machines and for implementing background step-wise tasks, either using active objects directly or through the CIdle wrapper class.

At this level of detail, active objects can seem quite complex and this chapter should mostly be used for reference until you start to work directly with complex active object code.