Wiley.Developing.Software.for.Symbian.OS.2nd.Edition.Dec.2007 (779887), страница 59
Текст из файла (страница 59)
Aside from thefact that you can’t specify a specific token count upon creation of amutex, the RMutex class is otherwise equivalent to RSemaphore.9.5.5 Critical SectionsCritical sections are regions of code in a process that should not be enteredsimultaneously by multiple threads. An example is a code region thatmanipulates static data, since it can obviously cause problems if multiplethreads are accessing the static data simultaneously. Symbian providesthe RCriticalSection class for this purpose. RCriticalSectionis very similar to RMutex except that it is always local to the process.
Acritical section is created and used as shown in the following lines:RCriticalSection crit;crit.Wait();// non re-entrant code section.crit.Signal();In this example, the non-re-entrant code section will only be able to beaccessed by one thread at a time. A second thread that attempts to executethis same code region will block at the Wait() call until the first threadhas finished executing the region and calls the Signal() method.Incrementing and decrementing global integer variables is a commonsituation in which critical sections are needed. Since it is awkward tocreate and surround these simple operations with critical section calls,Symbian provides some static functions in the User API class as aconvenience. The functions are:User::LockedInc(TInt& aValue)User::LockedDec(TInt& aValue)These functions will respectively increment and decrement the staticvalue whose reference is passed in aValue in a safe way – withoutrequiring you to explicitly use an instance of RCriticalSection.9.5.6Using Rendezvous()Both RThread and RProcess have a method called Rendezvous()that is used to indicate when a thread or process has reached a particularpoint in its execution.
This method is commonly used when you startanother process and want to block the original thread until the process ithas kicked off is started up and initialized. Below is an example:// main processvoid StartProcessL(){302PROCESSES, THREADS, AND SYNCHRONIZATIONRProcess proc;User::LeaveIfError(proc.Create(KMyExeFile));TRequestStatus stat;proc.Rendezvous(stat);proc.Resume();// Thread is executing. Can add code here to run in parallel...User::WaitForRequest(stat); // blocks until proc calls// RProcess::Rendezvous()// or process exitsUser::LeaveIfError(stat.Int());// leave if stat not KErrNone}// KMyExeFile Process#include <e32base.h>TInt E32Main(){// Start up boilerplate codeInitializeProcess(); // some function that initializes the processRProcess::Rendezvous(KErrNone); // signal that process is initialized// Clean up boilerplate codereturn(0);}There are two versions of Rendezvous(), one with the prototypeof void RProcess::Rendezvous(TRequestStatus& aStat) andone with the prototype of void RProcess::Rendezvous(TIntaRes).
The process that starts KMyExeFile uses the first versionof the function and, as you can see, it works in a similar manneras Logon() in that you start a process and then wait for an asynchronous event (which could also be done via an active object insteadof User::WaitForRequest(), which I’ve used in the example abovefor simplicity). For Rendezvous() the asynchronous event will occur if:•The process referenced by the process handle calls RProcess::Rendezvous(TInt aRes), where aRes is a status.
In this case, theasynchronous TRequestStatus variable will be set to aRes.• The process referenced by the process handle exits.• A panic occurs in the process referenced by the process handle.In the example, RProcess::Rendezvous(KErrNone); is called bythe KMyExeFile process after the process initializes, causing the asynchronous Rendezvous() function started in the parent process tocomplete with stat set to KErrNone.The RThread::Rendezvous() method works in the same way asRProcess::Rendezvous(), but at the thread level.Rendezvous() is commonly used when a client starts up a serverprocess and wants to know when the server process is running and readyto accept commands. We will come to this shortly in Chapter 10.10Client–Server FrameworkSymbian OS uses servers to manage resources centrally on behalf ofone or more clients.
A server does not normally have a graphical userinterface (GUI), and, in most cases, runs in its own process to provideprotection and modularity. (Servers and clients are always in differentthreads, although you can have multiple servers in the same process, oreven in the same thread.) Fundamentally, a server is simply a commandprocessing engine – it waits for a command from a client, executes theservice that corresponds to the command, returns the results to the client,and then waits for the next command.A client program uses a server through a client-side implementationclass – the programmer invokes the functions of the server through methods in the client class.
Each method sends the appropriate commandto the server and receives the command results back to return to thecaller. The client class handles the details of establishing a session withits associated server, as well as sending commands to the server andreceiving responses from it.Symbian OS uses servers to implement much of its functionality.
Infact, many of the Symbian OS API classes are client classes for servers.Many asynchronous functions are also implemented within a server, sincethe server runs within a separate thread from the client. Here are just afew examples of servers in Symbian OS:•The window server provides centralized access to the phone’s screen,as well as user input devices such as the keyboard and pointer deviceon smartphones with touchscreen input.
GUI applications are clientsof the window server, which allows them to concentrate on their ownimplementation, and let the server coordinate display usage betweenthe various applications that are running, and ensure that input eventsare routed to the appropriate application.304CLIENT–SERVER FRAMEWORK•The file system server handles all aspects of managing the files on thephone’s storage devices on behalf of client programs. This includescreating directories and files, reading and writing files, file accesscontrol, and copying and renaming. Clients interface to the serverthrough client-side API classes such as RFs and RFile.•The socket server manages the creation of network sockets, as wellas sending and receiving data through them.
The socket API classes(e.g., RSocket) act as clients to this server.•The font and bitmap server provides central control over fonts andbitmaps and allows them to be efficiently accessed (for example, byonly loading one copy of a ROM-based bitmap in to memory andproviding shared access to all the clients that need it).The fundamental classes that comprise the Symbian OS client–serverframework are public so that you can implement your own servers, alongwith client-side classes. This chapter gives a very basic introduction tocreating client–server software in Symbian OS. It describes the applicableclasses in the client–server framework, and walks through a simpleexample. Even if you do not implement your own server, understandingthis information will help when writing software that uses servers.10.1Client–Server OverviewA client command is submitted to the server, via the kernel, as a message.Servers process the messages one at a time – that is, further messagesare not processed until the currently-executing command is completed.This is because a server is actually implemented as an active objectand the server command handler is called from the server’s RunL()method.
So, as is the case for active objects in general, executing a servercommand ties up the entire thread – including any other active objects inthat thread – while that command is executing. In consequence, servercommands should be short and not block the thread for a long time.For each server, there is a corresponding client-side class, derivedfrom RSessionBase, that client programs use to submit commands.The client-side class handles the details of starting the server, and sendingmessages to and receiving messages from the server.In order for a client to use a server, the client first establishes acommunication context – known as a session – with the server. The clientthen sends commands to the server through this session.