Wiley.Symbian.OS.Internals.Real.time.Kernel.Programming.Dec.2005.eBook-DDU (779891), страница 28
Текст из файла (страница 28)
Since the most widely used of these isthe client-server mechanism used to communicate with system servers, Iwill start there.4.1 Client-server ITCClient-server is the original Symbian OS inter-thread communication(ITC) mechanism, having been present from the earliest implementationsof EPOC32 in the Psion Series 5 right up to the latest mobile phonesdeployed on the secure platform of Symbian OS v9.This mechanism allows a client to connect to a server using a unique,global name, establishing a ‘‘session’’ that provides the context for allfurther requests. Multiple sessions can be established to a server, both fromwithin a single thread and from within multiple threads and processes.Clients queue messages in the kernel; the server then retrieves thesemessages and processes each in turn.
When the processing of a requestis finished, the server signals the client that its request is complete.The implementation of the client-server mechanism guarantees requestcompletion, even under out-of-memory and server death conditions. Thecombination of a robust service request mechanism and a service provider118INTER-THREAD COMMUNICATIONguaranteed to be unique within the system was designed to make theclient-server mechanism suitable for providing centralized and controlledaccess to system resources.The managing of central resources using the client-server paradigm canbe seen throughout Symbian OS, with all the major services provided bySymbian OS being implemented using this method.
The file server (F32),the window server (WSERV), the telephony server (ETEL), the commsserver (C32) and the socket server (ESOCK) are all examples of centralresources managed by a server and accessed by a client interface to them.However, my intention in this chapter is to give you the inner workingsof client-server. It is not to teach you how to write your own server basedon this framework, or to show you how to use any of the existing serverswithin Symbian OS. For that, please refer to a Symbian OS SDK orSymbian OS Explained.1 Since this book focuses on EKA2, I will onlydiscuss the newest version of client-server (IPCv2).
I will summarize thedifferences from the legacy client-server framework (IPCv1) in a separatesection at the end.4.1.1 HistoryThe design and architecture of the client-server system have evolved withthe platform. In the original, pre-Symbian OS v6.0 implementation ofclient-server, a session was explicitly tied to the thread that had createdit. In Symbian OS v6.0, we generalized the concept of a session from thisvery ‘‘client-centric’’ implementation by adding the concept of a ‘‘sharedsession’’ that could be used by all the threads within the process.Though they appeared less client-centric in the user API, we implemented shared sessions within the kernel by creating objects tied tothe session to represent each ”share”. The share managed per-threadresources for the session, including a handle to the client thread for theserver. The handle from the share that corresponded to the thread thatsent a given message was then passed in the message delivered to theserver, so that when the server performed an operation to access a client’saddress space using a message handle, it was actually performed in thekernel using a handle associated with the client (in the share) rather thanthe message itself.With the advent of a secure platform on EKA2, Symbian OS clientserver has undergone a second evolution to an entirely ‘‘message-centric’’architecture known as IPCv2.
IPCv2 performs all accesses to memory ina client’s address space using a handle that is explicitly associated witha message, rather than the client that sent it. This allows us to deprecateand then remove APIs that allow direct access to an arbitrary thread’saddress space with nothing more than a handle to that thread.1Symbian OS Explained: Effective C++ Programming for Smartphones, by Jo Stichbury.Symbian Press.CLIENT-SERVER ITC119Earlier versions of EKA2 supported the legacy client-server APIs (IPCv1),using a special category of handle values, which directly referred tokernel-side message objects. The kernel passed these back as the clientthread handle in legacy messages.
When the kernel detected the use ofsuch a handle by legacy code during translation of a user-side handleto a kernel-side object, it located the corresponding kernel-side messageobject, extracted the client thread associated with that message, then usedit to perform the requested operation.
This legacy support was removedwith the move to the secure Symbian OS v9.Also, as part of the changes we made to implement a secure SymbianOS, we chose several categories of kernel-side objects to be able tobe shared securely and anonymously between two separate processes.Handles to such ‘‘protected’’ objects may be passed between processesboth by an extended ‘‘command line’’ API and via the client-servermechanism. We have extended the ‘‘command line’’ API to allow aparent to pass handles to its children, and we have extended the clientserver mechanism to enable a message to be completed with a handlerather than a standard error code.These ‘‘protected’’ objects can provide a mechanism for secure datatransfer between processes.
In particular, this new class of objects includesserver sessions, so that a session to a server can be shared between twoseparate processes. This means that in EKA2 a new method of sharing asession has now become possible: global (inter-process) session sharing.An interesting range of features can be designed using this new paradigm.For example, secure sharing of protected files between processes can beaccomplished using a shared file server session.4.1.2 Design challengesThe design of the kernel-side client-server architecture that I will describein more detail below is inherently a difficult matter.
Even in the mostbasic of configurations, with only a single client thread communicatingwith a single-threaded server, there are several things that can happen concurrently:• A client may send a message (asynchronously)• A client may close a session• Either the client or the server thread may die, resulting in kernel-sideobject cleanup being invoked• A server thread may complete a message (in a multi-threaded server,possibly a different thread than the one owning the handle to thekernel-side server object)• The server may close the handle to the kernel-side server object.120INTER-THREAD COMMUNICATIONAll of these actions require the state of kernel-side objects to be updatedand, since these actions may execute concurrently and preempt oneanother, they need to be carefully synchronized to avoid corruption ofthe kernel data structures. To make this task as simple and efficient aspossible, it was important that our design minimized the complexity ofthese objects, their states and the transitions needed to perform clientserver communication.Design simplicity was a key priority on EKA2.
This was because, if therequired synchronization (using the system lock) is not performed in aconstant-order manner, unbounded delays can occur and there is no possibility of Symbian OS offering hard real-time guarantees. Also, care needsto be taken to allow the server itself to respond to messages it has receivedwithin bounded time limits, so that servers which offer real-time guaranteesthemselves can be created. To this end, we added support in IPCv2 for asynchronous session creation and destruction, allowing the server’s RunL()duration to be small and bounded.
In this way we have provided a platformon which, for example, guaranteed multimedia services can be offered.However, the design of client-server on EKA2 is further complicateddue to the need to provide a secure IPC architecture. This has meantadding checks that operations performed on a client’s address space arevalid and providing a mechanism whereby the identity of a server maybe securely verified. It has also meant adding the ability for sessions tobe shared so that requirements for a secure platform such as secure filesharing can be implemented using client-server.I’ll now describe both the new user-side architecture of IPCv2 and thekernel architecture that supports it.4.1.3User-side architecture – serverThe key component in the user-side architecture is the server objectitself.
This is simply a standard active object,2 queuing requests on anasynchronous service API provided by the kernel to retrieve messages sentto the server by its clients. On the completion of such a request (receivinga message), the server active object’s RunL() usually dispatches themessage to a session object which has been created to manage theconnection between the server and its client.Session objects manage the server-side resources associated with a session and are created by the server when a connect message is receivedfrom the client.
In this case, the server’s RunL() calls the virtual NewSessionL() which returns an instance of a CSession2derived class. Youwould implement the server active object by deriving from CServer2 andthe session object by deriving from CSession2. The server-side architecture is shown in Figure 4.1 and CServer2 is implemented as follows:2For a comprehensive explanation of the use of active objects in Symbian OS C++,consult Symbian OS Explained by Jo Stichbury, Symbian Press.CLIENT-SERVER ITC121CServer2CSession2CSession2CSession2RServer2userkernel'cookie' == address of CSession2DSessionDSessionDSessionThread-ownedhandleDServerFigure 4.1 Server-side architectureclass CServer2 : public CActive{public:enum TServerType{EUnsharableSessions = EIpcSession_Unsharable,ESharableSessions = EIpcSession_Sharable,EGlobalSharableSessions = EIpcSession_GlobalSharable,};public:IMPORT_C virtual ∼CServer2() =0;IMPORT_C TInt Start(const TDesC& aName);IMPORT_C void StartL(const TDesC& aName);IMPORT_C void ReStart();inline RServer2 Server() const { return iServer; }protected:inline const RMessage2& Message() const;IMPORT_C CServer2(TInt aPriority,TServerType aType=EUnsharableSessions);IMPORT_C void DoCancel();IMPORT_C void RunL();IMPORT_C TInt RunError(TInt aError);IMPORT_C virtual void DoConnect(const RMessage2& aMessage);private:IMPORT_C virtual CSession2* NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const =0;private:TInt iSessionType;RServer2 iServer;RMessage2 iMessage;TDblQue<CSession2> iSessionQ;protected:TDblQueIter<CSession2> iSessionIter;};122INTER-THREAD COMMUNICATIONThe server keeps track of the current message it is processing (iMessage)and manages a queue of the session objects so they can be cleaned upduring the destruction of the server (iSessionQ).Upon reception of a (session) connect message, the server callsNewSessionL() to create a new CSession2-derived session objectand then appends the new session object to the end of the server queue.Finally, the server uses the connect message to pass a ‘‘cookie’’ (in theform of the address of the newly-created session object) to the kernel,which the kernel can then use to identify the particular session a givenmessage is associated with.The server implementation can over-ride DoConnect() in order toprovide asynchronous session creation.