Wiley.Symbian.OS.C.plus.plus.for.Mobile.Phones.Aug.2007 (779890), страница 10
Текст из файла (страница 10)
This modelFRAMEWORK BASICS31DBMSFileServerWindowServerAgendaServerKernelKernel mediatedApplicationFigure 2.4Typical concurrent processesfits very well with the traditionally event-driven nature of Symbian OS,where the user is interacting with the system and these interactions flowfrom the user to the system and back.In a monolithic and single-threaded OS, the programmer usuallyspawns threads in order to handle many events or requests asynchronously. In a microkernel OS such as Symbian OS, the concurrencyof the servers hosting the requested services gives that asynchronicity forfree. Within the single thread of a Symbian OS application, the programmer only needs to distribute requests to servers running concurrently inseparate threads.CancelRuScheduivelectrACancelAORequest SemaphoreFigure 2.5 Scheduling of active objectsnLststnLnLErRun rorue RequIsseRuue RequIsseAORustErRun rorAOue RequIsseCancelErRun ror32A SYSTEM INTRODUCTION TO SYMBIAN OSDBMSWindowServerFileServerKernelServerAgendaServerApplicationFigure 2.6 Active objects in concurrent processesActive objects fit very naturally into such an environment.
As illustratedin Figure 2.5, all Symbian OS active objects run under the control of theActive Scheduler, which is an AO queue management loop that waits ona special thread semaphore.In general, the application and the servers with which it communicateswill each own an active scheduler and a collection of active objects.Figure 2.6 illustrates this, and shows how active objects are used toimplement the interactions of Figure 2.4.In some circumstances a client may need to handle a service synchronously, and Symbian OS provides that functionality. However, thevast majority of services are handled asynchronously, with the clientusing the active object mechanism both to make a request and to handlethe server’s later request completion.Event handling with active objectsAn active object is normally responsible for asynchronously handlingrequests to one specific service provider.
Each active object has a virtualmember function called RunL(), which it must implement, as this isthe function that gets called when the object’s event happens. Theimplementation usually starts with some pre-processing to analyze theevent. It may complete the handling of the event without calling any otherfunctions, but in a framework RunL() usually calls one or more virtualfunctions that the programmer implements to provide specific behavior.The most important frameworks are for GUI applications and servers.An application such as the one in our example in Figure 2.7 uses theFRAMEWORK BASICS33GUI framework.
This framework analyzes input events, associates themwith the correct control, and then calls virtual member functions, such asOfferKeyEventL() to handle a key press.A server, for example the window server, uses the server frameworkto handle requests from client applications – including requests to drawon the screen, or to be notified about key events. Client requests areturned into messages, which are sent to the server. The server frameworkanalyzes these messages, associates them with the correct client, andhandles the client’s request by calling ServiceL() on the server-sideobject that represents the client.A server also uses its own active objects to handle events other thanclient requests – for instance, key events from the kernel.Event-handling exampleIf a Symbian OS application is running and a key is pressed, a smallcascade of events occurs.
These events are handled by at least threethreads, as illustrated in Figure 2.7.KeyboardinterruptKernel/driverISR/DFCkey eventWindow serverHandlekey eventUpdatewindowkey eventApplicationdrawrequestHandlekey eventCPU powerFigure 2.7 Events triggered by a key pressLet’s look at this cascade from a couple of perspectives. Firstly, fromthe whole-system point of view:• The I/O device responsible for looking after the keyboard generatesan interrupt.• The Interrupt Service Routine (ISR) translates this to an event. Itinterrogates the device, works out what ASCII key code to assign,and creates an event for whichever program is interested in raw keyevents – in any real Symbian OS system, that is the window server.34A SYSTEM INTRODUCTION TO SYMBIAN OS• The window server then works out which application is currentlyreceiving keystrokes, and sends the event to the application.• The Symbian OS application then handles the key – perhaps by addingtext to the document, then updating the display.• The window server updates the display in response to the application’s request.From the power-management point of view, power is needed for theCPU only while it’s doing something.
Power is turned on to handle aninterrupt, and turned off again when no more threads are eligible to run.You can also look at the tasks in the diagram and ask, ‘What otherevents might this task have to handle?’• The keyboard driver handles an interrupt, does minimal processing,and notifies a user-mode thread – in this case, the window server. Thekeyboard driver must also handle requests from the window serverfor key events. So the keyboard driver is an event-handling task thathandles two types of event: requests from a user-mode thread andhardware events from the keyboard.• The window server handles the key, does enough processing toidentify the application that is currently taking keys, and then notifiesthe application.
The window server, like the keyboard driver, alsohandles requests from the application for key presses, and the windowserver also performs screen drawing on behalf of all applications. Sothe window server is an event-handling task that handles these threeevent types (key events, requests to be notified about key events, andscreen drawing) plus many more (for example, pointer events andrequests to be notified about them).• The application is an event-handling task that handles key events aswell as others (for example, pointer events).Symbian OS C++ Exception HandlingNative Symbian OS C++ programs use an exception-handling mechanismwhich is not compatible with the ISO C++ 0x exception-handling scheme(the design of Symbian OS predates ISO/IEC 14882 1998/2003).The Symbian OS C++ exception-handling philosophy is to be ‘in yourface’.
Symbian OS C++ programmers have to understand, handle andimplement trapping, throwing and heap-allocated object tracking as partof their program’s design, and not as an afterthought as is often the casein other frameworks.Symbian did not implement exceptions in the ‘standard way’ for historic and efficiency reasons. When Symbian OS was being born, supportin both free and commercial compilers for ‘standard’ C++ exceptions wasFRAMEWORK BASICS35poor or, in many cases, absent. This was in 1990, when Bjarne Stroustrupcalled support for exceptions ‘experimental’ [BSI 2005]; C++ was firststandardized only in 1998.
In addition, the support that did exist forhandling exceptions was inefficient and produced overly large binaries,a serious problem for the ROM-based products of the early nineties.Symbian OS C++ makes use of the cleanup stack in order to keep trackof heap-allocated objects in the face of exceptions. The cleanup stack wasbriefly introduced in Chapter 1 without much explanation; this chapterprovides an overview of its purpose and use, and Chapter 4 covers thesubject in depth.Here is a brief example using the cleanup stack:SomeMethodL(){tmpObject = new (ELeave) CHeapyObject(); // Note overloaded newCleanupStack::PushL(tmpObject);//track objectDoSomethingThatMayLeaveL(); // this call may throw an exceptionCleanupStack::Pop(tmpObject); // we know an exception was// not thrown and we may remove// the object from the stack...// ...and pass ownership of that object// OR possibly even do the following insteadCleanupStack::PopAndDestroy(tmpObject);}So how does the cleanup stack work?• It stores pointers to objects that must be destroyed if an exception(a.k.a.
Leave) occurs.• These pointers are stored in nested levels.• Each such level is marked by the TRAP macro, which functions ratherlike a C setjump/longjump with executive call.• When a Leave occurs, the stack calls all destructors (and cleanupitems) of objects belonging to the corresponding TRAP level.• Also, when a Leave occurs, the stack unwinds to the point markedby the corresponding TRAP, returning an exception error code.An exception is thrown in Symbian OS C++ by a call toUser::Leave(), and caught by means of the TRAP macro.CleanupStack::PushL(something);// will stay on the CleanupStack if// it Leaves belowTRAPD(err,SomeMethodL());if (err == KErrNone)36A SYSTEM INTRODUCTION TO SYMBIAN OS{//do something}else{// start handling the exception// and possibly propagate it by another LeaveUser::Leave(err);}// possibly pop somethingAs is evident from the code snippet above, Symbian OS C++ propagatesthe exception context in the form of integers (in this case err), whichdiffers from how standard ISO C++ works.