0% found this document useful (0 votes)
706 views

Part09 ClientServer

This document discusses the client-server framework model on Symbian OS. It describes the client-server pattern, where a client makes requests to a server which handles the requests. Servers are used to manage shared access to resources and run in separate processes from clients for security and isolation. The client-server framework implements both system servers, which run for the life of the OS, and transient application servers, which start when needed and stop when no longer needed. Client and server communication occurs through message passing due to their separate memory spaces.

Uploaded by

Symbian
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
706 views

Part09 ClientServer

This document discusses the client-server framework model on Symbian OS. It describes the client-server pattern, where a client makes requests to a server which handles the requests. Servers are used to manage shared access to resources and run in separate processes from clients for security and isolation. The client-server framework implements both system servers, which run for the life of the OS, and transient application servers, which start when needed and stop when no longer needed. Client and server communication occurs through message passing due to their separate memory spaces.

Uploaded by

Symbian
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 105

Fundamentals of Symbian C++

Client-Server Framework
Part One

This work is licensed under the Creative Commons Attribution-Share Alike 2.0 UK: England & Wales License.

To view a copy of this license, visit http://creativecommons.org/licenses/bysa/2.0/uk/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California,
94105, USA.
Client Server

Client-Server Framework

This Lecture Examines


•  The client–server framework model on Symbian OS
•  Describes the theory behind the client–server pattern
•  Why it is used on Symbian OS and how it works
•  The implementation classes involved
•  The run-time performance of using the client–server model

Fundamentals of Symbian C++ 2


Client Server

The Client–Server Pattern

•  Know the structure and benefits of the client–server framework on


Symbian OS
•  Understand the different roles of system and transient servers, and
match the appropriate server type to examples of server
applications

Fundamentals of Symbian C++ 3


Client Server

The Client–Server Pattern


In the client–server pattern
•  A client makes use of services provided by a server
•  The server receives request messages from its clients and handles
them
•  Either synchronously or asynchronously

Servers are typically used to manage shared access to system


resources and services
•  The use of a server is efficient as it can service multiple client
sessions
•  And be accessed concurrently by clients running in separate
threads

Note
•  The client–server framework can also be used to wrap code which
contains writable static data

Fundamentals of Symbian C++ 4


Client Server

Client-Server Conceptual Schematic

client server

Calling Client
#1

Client-Side
Server A Resource
Calling Client API
#2

Calling Client
#3

Fundamentals of Symbian C++ 5


Client Server

The Client–Server Pattern

A server protects the integrity of the system


•  It can ensure that resources are shared properly between clients
- So all clients use those resources correctly

On Symbian OS
•  The server runs in its own process
•  It has a separate isolated address space
•  The only access a client has to the services in question is through a
well-defined interface

By employing a server in a separate process


•  The OS can guarantee that badly programmed or malicious clients
cannot corrupt any of the resources the server manages

Fundamentals of Symbian C++ 6


Client Server

The Client–Server Pattern


A server must guard against invalid or out-of-sequence client
requests
•  It should terminate the offender
- Typically by raising a panic on the client process

Most of the system services on Symbian OS are implemented


using a Client-Server Framework
•  Particularly those providing asynchronous functionality

For example
•  The window server (for access to UI resources such as the screen and
keypad)
•  The serial communications server (for access to the serial ports)
•  The file system server

Fundamentals of Symbian C++ 7


Client Server

The Client–Server Pattern

There are several ways in which a server can


be started and stopped:

System servers (for example the file server)


are essential to the running of the operating
system
•  They are started by Symbian OS as part of OS
startup
•  They run for the entire time the OS is running

If they need to terminate unexpectedly


•  They will typically force a reboot of the phone

Fundamentals of Symbian C++ 8


Client Server

The Client–Server Pattern

Application servers are only needed when


certain applications are running
•  Started when clients need to connect to them
•  Only a single instance of the server runs (started
by the first client that needs the server)

When the last client session closes


•  The server should terminate to save system
resources

This type of server is known as a transient


server

Fundamentals of Symbian C++ 9


Client Server

The Client–Server Pattern

Other servers are required on a per-application basis


•  For example the POSIX server
•  Started with that application and closed when it terminates
•  Multiple applications may use the same server implementation
•  Each application will have its own private instance

Fundamentals of Symbian C++ 10


Client Server

Fundamentals of the Symbian OS Client–


Server Framework

•  Know the fundamentals of the Symbian OS client–server


implementation

Fundamentals of Symbian C++ 11


Client Server

Fundamentals of the Client–Server Framework

A Symbian OS server
•  Always runs in a separate thread to its clients
•  Often - but not always - runs within a separate process

The memory of each process is isolated


•  Thus client and server cannot access each other’s virtual address
spaces

For this reason


•  All client–server communication takes place by message passing
•  Data transfer between the separate threads/processes is mediated
by the kernel
- Known as inter-thread transfer (ITC) or inter-process transfer (IPC)
respectively

Fundamentals of Symbian C++ 12


Client Server

Process vs Thread

Process B
Process Process A

Thread#1 Thread#2 Thread#1 Thread#1

Msgs mediated

Msgs mediated
Client Server
Client Server
by kernel

by kernel
A client and server sharing the same A client and server in separate process
process space communicating by ITC spaces communicating by IPC

Fundamentals of Symbian C++ 13


Client Server

Fundamentals of the Client–Server Framework

The communication channel used to pass messages


between the client and server is known as a session

A session is initiated by a client


•  The server-side representation is created by the kernel

The kernel also acts as an intermediary for all client–


server communication

Fundamentals of Symbian C++ 14


Client Server

Fundamentals of the Client–Server Framework

The client makes a request to the server


•  Using a message object that identifies the nature of the
request
•  And additional parameter data

For simple transactions this is sufficient - for more


complex data
•  Inter-thread data transfer functions are used to transfer
parameter data and return data

Fundamentals of Symbian C++ 15


Client Server

Fundamentals of the Client–Server Framework

A typical server
•  Has client-side code that formats requests to pass to the
server
•  Requests go via the kernel

For example
•  A client of the Symbian OS file server (efile.exe)
•  Is actually a client of the file server’s client-side
implementation
•  Linking against the DLL which provides it (efsrv.dll)
•  The client-side implementation DLL hides the details of the
private client–server communication protocol from the
calling code that uses it

Fundamentals of Symbian C++ 16


Client Server

Concrete File Server Example

Process Boundary

Links to efsrv.lib and calls API


Client-Server communication
methods on it, such as
(kernel-mediated messages)
RFs::Connect()

mytest.exe efsrv.dll efile.exe

Client-side File
File Server
Server
Implementation

Fundamentals of Symbian C++ 17


Client Server

Fundamentals of the Client–Server Framework

Servers are often used


•  To provide asynchronous services to their clients
•  Because they run in a separate thread to their clients

A client
•  May submit a number of asynchronous requests to a server (up to
255)
•  May only ever have one synchronous request outstanding at a time

Fundamentals of Symbian C++ 18


Client Server

Symbian OS Client–Server Classes

•  Know the classes used by the Symbian OS client–server


framework, and basic information about the role of each:
•  RSessionBase
•  TIpcArgs
•  TSecurityPolicy
•  RMessage2
•  CSession2
•  CServer2
•  CPolicyServer
•  Recognize the objects that a server must instantiate when it starts
up
•  Understand the mechanism used to prevent the spoofing of servers
in Symbian OS

Fundamentals of Symbian C++ 19


Client Server

Symbian OS Client–Server Classes

This section introduces


•  The classes that are used to implement the Symbian OS client–
server framework
•  The classes discussed are those introduced for secure inter-
process communication (IPC) in Symbian OS v8.1b and later

Fundamentals of Symbian C++ 20


Client Server

Symbian OS Client–Server Classes


The client-side representation

RHandleBase

RSessionBase

•  Deriving from RSessionBase - the main client-side


class
•  The base class for classes that own handles to other
objects
•  Often those created within the kernel

An RSessionBase object
•  Uniquely identifies a client–server session
•  Is used to send messages to the server

Fundamentals of Symbian C++ 21


Client Server

Symbian OS Client–Server Classes

The majority of the methods of RSessionBase


•  Are protected to ensure that the client-side class that accesses a
server does not directly expose access to the server

Instead, the class derives from RSessionBase


•  Exporting functions that call the protected RSessionBase
methods
•  Thus “wrapping” communication with the server

Fundamentals of Symbian C++ 22


Client Server

Client-Server Classes

CServer2

CSession2

Server

Client These methods are protected (i.e. a private protocol)

RSessionBase

Public API methods

RMyClientAPI

Fundamentals of Symbian C++ 23


Client Server

Symbian OS Client–Server Classes

For example
•  Class RFs derives from RSessionBase

Providing access to the file server


•  Through functions such as RFs::Delete() and
RFs::GetDir()
•  Allowing communication with the file server without
exposing direct access to it

Fundamentals of Symbian C++ 24


Client Server

Symbian OS Client–Server Classes

Class RSessionBase
•  Has several overloads of CreateSession()
•  To start new client–server sessions

Typically called by client-side implementation code in an


exported method
•  such as Open() or Connect(), which are used to initiate
a session

Fundamentals of Symbian C++ 25


Client Server

Symbian OS Client–Server Classes

For example
•  Starting a session with the file server requires a call
to RFs::Connect()
•  Which calls RSessionBase::CreateSession()
•  When the session is opened successfully
corresponding kernel and server-side objects are
created

Fundamentals of Symbian C++ 26


Client Server

Symbian OS Client–Server Classes

A server has a unique name


•  Which must be passed to
RSessionBase::CreateSession()
•  To connect the client to the correct server

The client-side implementation does this


•  So the calling code does not need to know the name of the
server

Fundamentals of Symbian C++ 27


Client Server

Symbian OS Client–Server Classes

In order to stop “spoof” servers from taking the names of


critical system servers
•  The namespace is partitioned into “normal” and “protected” parts

The protected server namespace is defined by all server


names beginning with the “ !” character
•  Registering server objects that have names beginning with this
character is only permitted for processes possessing the
ProtServ capability

The ProtServ capability


•  Allows a server process to register with a protected name
•  We will come back to this in a later lecture

Fundamentals of Symbian C++ 28


Client Server

The RSessionBase class

Several overloads of
RSessionBase::CreateSession()
•  Take an integer parameter aAsyncMessageSlots
•  This value reserves a number of slots

The slots reserve slots for outstanding asynchronous


requests
•  That is the number of requests the client session may
have with the server
•  The maximum number of slots that may be reserved for
each server is 255

Fundamentals of Symbian C++ 29


Client Server

The RSessionBase class

Other overloads of CreateSession()


•  Do not pre-allocate a maximum number of message slots
•  Slots are taken from a kernel-managed global pool of up to
255 message slots for that server

There are only 255 slots per server available to the


whole system

Fundamentals of Symbian C++ 30


Client Server

The RSessionBase class

If the number of outstanding requests exceeds the


number of slots in the system pool
•  Or the number reserved for a particular session

The asynchronous request fails to be submitted


•  And completes immediately with the error
KErrServerBusy

Fundamentals of Symbian C++ 31


Client Server

The RSessionBase Class

Other parameters in the overloads of CreateSession() take a


TSecurityPolicy object
•  This allows the client code to specify criteria for the server

Such as
•  The secure ID of the server process
•  Or the capabilities of the calling process

The TSecurityPolicy class is discussed in more detail shortly


•  Secure IDs, capabilities and platform security are also discussed in a
later lecture

Fundamentals of Symbian C++ 32


Client Server

The RSessionBase Class

A request to a server is issued


•  By calling RSessionBase::SendReceive() or
RSessionBase::Send()

The RSessionBase::SendReceive() method is


overloaded to handle synchronous and asynchronous requests
•  The asynchronous request method takes a TRequestStatus&
parameter
•  The synchronous version returns the result in a TInt return value.

The RSessionBase::Send() method


•  Sends a message to the server but does not receive a reply
•  In practice this function is rarely used

Fundamentals of Symbian C++ 33


Client Server

The Send() and SendReceive() methods

The Send() and SendReceive() methods


•  Take a 32-bit argument to identify the client request
•  This is typically defined in an enumeration shared
between the client and server code

The request identifiers do not need to be made public


•  Neither does the order in which parameter data is passed
within a TIpcArgs object

Fundamentals of Symbian C++ 34


Client Server

The Send() and SendReceive() methods

Request identification and parameter data


•  Are a private protocol between the client- and server-
side implementations

The protocol is specific to each client–server


implementation
•  Wrapped by exported public methods in the client-side
implementation
•  The calling code does not need to ‘understand’ the
protocol

Fundamentals of Symbian C++ 35


Client Server

Disconnection from the Server

Typically a class used to access a server has a


termination method
•  Usually called Close() since the class is usually a R class
type and this is generally used to clean up R class objects

Internally this method will call


RHandleBase::Close()
•  Which sends a disconnection message to the server
•  And sets the session handle to zero

On receipt of this message the server ends its session


•  By destroying any associated objects that represent the
session server-side

If the client has any outstanding requests


•  They are not guaranteed to be completed

Fundamentals of Symbian C++ 36


Client Server

Disconnection from the Server

Symbian OS considers client requests that are outstanding


following a call to Close() as a client-side programming error
•  So raises a panic

The server may make an attempt to complete the session’s


outstanding requests after the session is closed
•  This is not always possible!

So the client ...


•  Should ensure that it cancels all requests before the Close() call

Fundamentals of Symbian C++ 37


Client Server

Disconnection from the Server

If a client process terminates without calling


RSessionBase::Close()
•  The kernel is responsible for any server-side cleanup necessary

If a server process terminates unexpectedly


•  Any waiting client requests will be completed with the error code
KErrServerTerminated
•  This gives the client the opportunity to perform cleanup on any
session handles

Once a client or server terminates (even if it later re-starts)


•  Sessions used prior to termination cannot be re-used

Fundamentals of Symbian C++ 38


Client Server

Session Sharing

It may be possible for more than one user client


•  To share the same RSessionBase object

An open client session may be shared by


•  All the threads in a client process
•  And with threads in other processes
•  Provided the server supports session sharing

Some servers restrict session sharing to the thread


which connected to the server
•  And raise a panic if an attempt is made to share them
•  This was always the case until sharable sessions were
introduced in Symbian OS v6.0

Fundamentals of Symbian C++ 39


Client Server
Session Sharing
CServer2

CSession2

RSessionBase::CreateSession()
For same process sharing RSessionBase::ShareAuto()
For different process sharing RSessionBase::ShareProtected()
Server

Thread #1 Thread #2
(may be in the same process or in
a different process to Thread #1)
RSessionBase

Client 1 Client 2

Fundamentals of Symbian C++ 40


Client Server

Session Sharing

On the client side


•  If a session can be shared ...

The first connection to the server


•  Should be made as normal using
RSessionBase::CreateSession()

Once the session is opened


•  RSessionBase::ShareAuto() should be called on it
•  To make it sharable by other threads in the same process

Fundamentals of Symbian C++ 41


Client Server

Session Sharing

If the session handle


•  Is to be used by threads within a different process
•  RSessionBase::ShareProtected() must be called
on the handle

Alternatively
•  A sharable session can be created by calling the overload
of RSessionBase::CreateSession()

Which takes a TIpcSessionType parameter


•  EIpcSession_Sharable for a process-sharable (same
process)
•  EIpcSession_GlobalSharable for a globally sharable
session (different processes)

Fundamentals of Symbian C++ 42


Client Server

The TIpcArgs class

The TIpcArgs class is used to package the arguments to be


sent to a server

For example
TInt SendReceive(TInt aFunction, const TIpcArgs &aArgs);

A TIpcArgs object
•  Constitutes the “payload” for a client–server request
•  It can package up to four arguments together
•  And contains information about each argument’s type

The object can contain no arguments at all


•  For requests that have no associated payload data

Fundamentals of Symbian C++ 43


Client Server

The TIpcArgs class

The TIpcArgs class


•  Has a default constructor and four templated constructors
•  Allowing an object of this type to be constructed for between zero
and four arguments

Internally
•  The arguments are stored in a simple array of four 32-bit values
•  Consecutive arguments in the constructor’s parameter list are put
into consecutive slots in the array

The class also has


•  A group of overloaded Set() functions
•  Used to explicitly set argument values into specific slots within the
array

Fundamentals of Symbian C++ 44


Client Server

The TIpcArgs class

The Set() functions


•  Specify the slot to use and the 32-bit value to
store

Which may be
•  a TInt
•  an RHandleBase
•  a TAny*
•  a TDes16*
•  a TDes8*

More class TIpcArgs coming up later!

Fundamentals of Symbian C++ 45


Client Server

The TSecurityPolicy class

The TSecurityPolicy class


•  Represents a generic security policy
•  Is passed by the client-side implementation code to the server

The owning client


•  Would pass one (or more) of these objects to the server
•  Specifying which security checks should be done on the client
process
•  That is specify access rights the user of the client API has to the
server
•  Before allowing it access to the server

Fundamentals of Symbian C++ 46


Client Server

The TSecurityPolicy class

TSecurityPolicy can specify a security policy consisting of:


•  A check for between 0 and 7 capabilities
•  A check for a given Secure Identifier along with 0–3 capabilities
•  A check for a given Vendor Identifier along with 0–3 capabilities.

If multiple capabilities are specified


•  All of them must be present for the security check to succeed.

Fundamentals of Symbian C++ 47


Client Server

The RMessage2 class

The RMessage2 class


•  Represents a client request server-side
•  The 2 in the name indicates that it is the second version of this
class

The original RMessage class


•  Was used in versions of Symbian OS up to v8.1b
•  But has subsequently been replaced
•  Due to the introduction of secure inter-process communication

Fundamentals of Symbian C++ 48


Client Server

RMessage2 in Relation to TIpcArgs


client Process Boundary server

Client #1 CServer2

MySet(TInt aVal)

The TIpcArgs translate server side after


going through kernel mediation to an
RMyClassSession
RMessage2 object
Basic wrapper to provide clients with
TIpcArgs class marshals
a simple interface to the server RMessage2::Function() provides
the data and the function
identification‘opcode’ an opcode for MySet()
TIpcArgs(T0 a0)
RMessage2::Int0() provides the 1st arg
aVal is wrapped in the TIpcArgs
template class (T0 is TInt and a0 is
aVal)

Fundamentals of Symbian C++ 49


Client Server

The RMessage2 class

Class RMessage2 derives from RMessagePtr2

RMessagePtr2

RMessage2

•  RMessagePtr2 provides a handle to the message sent by the


client
•  RMessage2 extends it by encapsulating the data associated
with the message

Each client request to the server is represented by a


separate RMessage2 object
•  Clients do not use RMessage2 objects directly

Fundamentals of Symbian C++ 50


Client Server

The RMessage2 class

The RMessage2 object


•  Is the server-side equivalent of the TIpcArgs object and request
identifier
•  Is created by the kernel when a client makes a request

For example
•  Calling RSessionBase::SendReceive()
•  Connecting to the server or closing the session

Fundamentals of Symbian C++ 51


Client Server

The RMessage2 class

The 32-bit request identifier


•  Also known as an operation code or opcode
•  Can be retrieved by calling Function()

The four argument slots that TIpcArgs provides


•  May be accessed by calling Int0()
•  To return a 32-bit value from the first element of the request array
•  Int1() to return the second element
•  So on to the fourth element, returned by Int3()

Fundamentals of Symbian C++ 52


Client Server

The RMessage2 class

In a similar manner
•  Ptr0() returns the contents of the first element in the request array as a
TAny* pointer
•  Ptr1() the contents of the second element
•  So on to the fourth element, returned by Ptr3()

Thus as layout of the parameters in the request data array


•  Is pre-determined for each client request
•  It can retrieve the data from the appropriate slot of the RMessage2
object

Fundamentals of Symbian C++ 53


Client Server

The RMessage2 class

The pointers returned


•  From the methods Ptr0(), Ptr1(), Ptr2() and Ptr3()
•  Cannot be used directly by the server code if they refer to the
address space of a client running in a different process

The server must instead use


•  The overloaded ReadL() and WriteL() methods of
RMessagePtr2
•  Which use kernel-mediated inter-process communication to
transfer the data

Fundamentals of Symbian C++ 54


Client Server

The RMessage2 class

When the server has serviced a client request


•  It calls RMessagePtr2::Complete() on the RMessage2
•  This notifies the client of completion of request

This method
•  Wraps a call to RThread::RequestComplete() on the client’s
thread handle

The integer value passed to RequestComplete()


•  Is written into the client’s TRequestStatus value
•  The request semaphore for the client thread is signaled

Fundamentals of Symbian C++ 55


Client Server

The CSession2 class

CSession2 is an abstract base class


•  That represents a client session within the server

CBase

CSession2

For each RSessionBase-derived object on the client side


•  There is an associated CSession2-derived object on the server side
•  Created as part of the client’s connect request via
RSessionBase::CreateSession()
•  The class is named to reflect that it is the second version of the class
•  Updated for secure IPC in Symbian OS v8.1

Fundamentals of Symbian C++ 56


Client Server

The CSession2 class

Classes derived from CSession2


•  Handle incoming client requests through their implementation of the pure
virtual ServiceL() method

Typically ServiceL()checks the incoming message parameter to


see which request the client has submitted
•  Then handles it by unpacking the message
•  Uses the incoming parameters accordingly

When the request has been handled


•  Complete() is called on the associated message object
•  To notify the client thread of request completion

Fundamentals of Symbian C++ 57


Client Server

The CServer2 class


The server-side base class is CServer2
•  It is an abstract base class which must be implemented by each
server

CActive

CServer2

The system ensures


•  There is only one CServer2-derived active object created for each
uniquely-named server

CServer2::StartL()
•  Adds the server to the active scheduler
•  Initiates the first message receive request

Fundamentals of Symbian C++ 58


Client Server

The CServer2 class

The CServer2 active object accepts requests from


all clients of the server as events
•  Receiving notification of each incoming request from the
kernel

The event-handler method RunL() executes


•  Using Message() to inspect the RMessage2

To determine whether the CServer2-derived object


can handle the request itself
•  For example - for connection or disconnection requests

Fundamentals of Symbian C++ 59


Client Server

The CServer2 class

If the CServer2::RunL() cannot handle the


request
•  It directs the request to the ServiceL() method
of the appropriate server-side CSession2-
derived class

Having serviced each request


•  RunL() resubmits a “message receive” request
•  Awaits further client requests

Fundamentals of Symbian C++ 60


Client Server

Active Object Conventions

As CServer2 is derived from CActive


•  The conventions for active objects should be followed

In particular
•  Requests within the server should be handled quickly and
efficiently

For example
•  A long-running asynchronous request should be delegated to
another active object running within the server
- So it can be processed as a series of incremental tasks

•  This will allow the server to remain responsive to incoming


requests while processing the long-running request in the
background

Fundamentals of Symbian C++ 61


Client Server
The CPolicyServer class

CPolicyServer implements a security policy

CServer2

CPolicyServer

•  By extending the normal CServer2 class


•  The class checks a received message against a security policy
•  Performing actions depending on the result of the check
•  The exact behavior is defined on construction

On receipt of a message
•  The message opcode number is used to retrieve the associated
policy index

Which is used as follows depending on its value ...


Fundamentals of Symbian C++ 62
Client Server

The CPolicyServer Policy Enumerations

TSpecialCase::EAlwaysPass
•  The message is processed as normal by passing it to the
ServiceL() method of a session
•  In the case of a connection message - creating a new session

TSpecialCase::ENotSupported
•  The message is completed with KErrNotSupported

TSpecialCase::ECustomCheck
•  Makes a call to the virtual function CustomSecurityCheckL()
•  Returns a value to indicate whether to process the message
•  Or cause it to fail

Fundamentals of Symbian C++ 63


Client Server

The CPolicyServer Policy Enumerations

If none of the enumerations apply


•  The policy index is used as a lookup value
•  In an array of security policies given on
construction of the CPolicyServer object

The associated policy element


•  Is used to check the message being processed

If the message meets the attributes specified in


the policy
•  It is processed as normal

Fundamentals of Symbian C++ 64


Client Server

The CPolicyServer class

The final course of action is


•  CPolicyServer::CheckFailedL() is called
•  With the action value specified in the associated policy element

The action will either


•  Complete the request with KErrPermisisonDenied
•  Panic the client thread
•  Call a custom failure action
CPolicyServer::CustomFailureActionL()

Fundamentals of Symbian C++ 65


Client Server

Server-Side Startup

When creating a server it is necessary to allocate


•  A cleanup stack
•  An active scheduler for the server

This should be done on startup


•  The cleanup stack is allocated by a call to
CTrapCleanup::New()
•  The active scheduler is created and installed as described in the
active object lecture

Fundamentals of Symbian C++ 66


Client Server

Client–Server Framework

  The Client–Server Pattern

  Fundamentals of the Symbian OS Client–Server


Framework

  Symbian OS Client–Server Classes

  Client–Server Data Transfer

Fundamentals of Symbian C++ 67


Client Server

Client-Server Framework

Part Two

Fundamentals of Symbian C++


Client Server

Client-Server Framework

This Lecture Examines


•  A ‘classic’ client-server example
•  The run-time performance of using the client–server model

Fundamentals of Symbian C++ 69


Client Server

Recap: Client-Server Classes

CServer2

CSession2

Server

Client These methods are protected (i.e. a private protocol)

RSessionBase

Public API methods

RMyClientAPI

Fundamentals of Symbian C++ 23


70
Client Server

Recap: RMessage2 in Relation to TIpcArgs


client Process Boundary server

Client #1 CServer2

MySet(TInt aVal)

The TIpcArgs translate server side after


going through kernel mediation to an
RMyClassSession
RMessage2 object
Basic wrapper to provide clients with
TIpcArgs class marshals
a simple interface to the server RMessage2::Function() provides
the data and the function
identification‘opcode’ an opcode for MySet()
TIpcArgs(T0 a0)
RMessage2::Int0() provides the 1st arg
aVal is wrapped in the TIpcArgs
template class (T0 is TInt and a0 is
aVal)

Fundamentals of Symbian C++ 71


Client Server

Client–Server Data Transfer

•  Know the basics of how clients and servers transfer data for
synchronous and asynchronous requests
•  Recognize the correct code to transfer data from a client derived
from RSessionBase to a Symbian OS server
•  Know how to submit both synchronous and asynchronous client–
server requests
•  Know how to convert basic and custom data types into the
appropriate payload which can be passed to the server, as both
read-only and read/write request arguments

Fundamentals of Symbian C++ 72


Client Server

Client–Server Data Transfer

The example we are going to walkthrough assumes that the


client and server are running in separate processes
•  Which means that data transfer between them requires inter-
process communication (IPC)

The parameter data can never be transferred using simple C++


pointers
•  As the server never has direct access to the client’s address space
(or vice versa)

This data is passed from the client to the server


•  As a 32-bit value in the request message itself
•  Or by passing a pointer to a descriptor in the client address space
- Which the server accesses using kernel-mediated data transfer

Fundamentals of Symbian C++ 73


Client Server

Client–Server Data Transfer

For those interested...


•  The example uses the Labors of Hercules (a Greek myth) to
demonstrate data transfer
•  This site http://www.mythweb.com/hercules/index.html provides a
background to the myth

Fundamentals of Symbian C++ 74


Client Server

Client–Server Data Transfer

A set of enumerated values is used to identify which service


the client requests from the server
enum THerculeanLabors
{
ESlayNemeanLion,
ESlayHydra,
ECaptureCeryneianHind,
ESlayErymanthianBoar,
ECleanAugeanStables,
ESlayStymphalianBirds,
ECaptureCretanBull,
ECaptureMaresOfDiomedes,
EObtainGirdleOfHippolyta,
ECaptureOxenOfGeryon,
ETakeGoldenApplesOfHesperides,
ECaptureCerberus,
ECancelCleanAugeanStables,
ECancelSlayStymphalianBirds
};

Fundamentals of Symbian C++ 75


Client Server

Client–Server Data Transfer

A TIpcArgs object
•  Is instantiated and passed to the server with each request

Where parameter data is to be passed to the server


•  It is passed to the TIpcArgs object on construction

Where there are no accompanying request parameters


•  The TIpcArgs object is constructed empty - by default
void RHerculesSession::CancelCleanAugeanStables()
{
SendReceive(ECancelCleanAugeanStables, TIpcArgs());
}

•  The following example describes how to implement client-side


request code for a range of different parameter types

Fundamentals of Symbian C++ 76


Client Server

Read-Only Basic Types

The following shows how to pass descriptors and integers to


the server:
// Request which passes a constant descriptor (aDes)
// and a "read-only" integer (aVal) to the server

TInt RHerculesSession::SlayNemeanLion(const TDesC8& aDes, TInt aVal)


{
TIpcArgs args(&aDes, aVal);
return (SendReceive(ESlayNemeanLion,args));
}

Fundamentals of Symbian C++ 77


Client Server

Custom Types: Simple Types (T-class objects)


The previous slide shows how integer and descriptor data are
passed to a server

But what about custom data types?


•  RHerculesSession::SlayHydra() passes an object of type
THydraData
•  THydraData is a simple structure containing only built-in types

struct THydraData
{
TVersion iHydraVersion;
TInt iHeadCount;
};

•  TVersion is a Symbian OS class defined in e32cmn.h


•  See next slide

Fundamentals of Symbian C++ 78


Client Server

Custom Types: Simple Types (T-class objects)

TVersion is a Symbian OS class defined in e32cmn.h

class TVersion
{
public:
IMPORT_C TVersion();
IMPORT_C TVersion(TInt aMajor, TInt aMinor, TInt aBuild);
IMPORT_C TVersionName Name() const;
public:
TInt8 iMajor;
TInt8 iMinor;
TInt16 iBuild;
};

A THydraData object is 64 bits in size

Fundamentals of Symbian C++ 79


Client Server

Custom Types: Simple Types (T-class objects)

Because the THydraData object is 64 bits in size


•  It is too large to be passed to the server as one of the 32-bit elements of
the request data array
•  A pointer to the object must instead be marshaled across the client–
server boundary.

Server-side code
•  Should not attempt to access a client-side object directly through a C++
pointer passed from the client to server
•  The server code in this examples runs in a different process therefore
different virtual address space
•  Any attempt to use a client-side pointer, server-side will result in an
access violation (and a panic)

Fundamentals of Symbian C++ 80


Client Server

Custom Types: Simple Types (T-class objects)

Data transfer must be performed using the inter-thread data


transfer methods of class RMessagePtr2

Thus before the THydraData object is passed to the server it


must be “descriptorized”
•  The package pointer template classes TPckg and TPckgC can be
used to wrap a flat data object such as THydraData within a pointer
descriptor - TPtr8

Fundamentals of Symbian C++ 81


Client Server

Client–Server Data Transfer

The SlayHydra() method of RHerculesSession


•  Creates a TPckg<THydraData> around its THydraData
parameter
•  The resulting descriptor has a length equivalent to the size in bytes
of the templated object it wraps (64 bits = 2 bytes)
•  The iPtr data pointer of the TPtr8 addresses the start of the
THydraData object

TInt RHerculesSession::SlayHydra(THydraData& aData)


{
TPckg<THydraData> data(aData);
TIpcArgs args(&data);
return (SendReceive(ESlayHydra, args));
}

Fundamentals of Symbian C++ 82


Client Server

Custom Types: C- and R-class Objects

What if the custom data


•  Has variable length?
•  Or does not just contain flat data but owns pointers to other objects?

The following code shows how an object of a C class containing a


pointer to another object or variable-length data is marshaled from
client to server

The CHerculesData class


•  Owns two heap descriptor pointers and an integer value

It must have utility code


•  to put all its member data into a descriptor client-side - externalization
•  and corresponding code to recreate it from the descriptor server-side -
internalization

Fundamentals of Symbian C++ 83


Client Server

Custom Types: C- and R-class Objects


class CHerculesData : public CBase
{
public:
static CHerculesData* NewLC(const TDesC8& aDes1,
const TDesC8& aDes2, TInt aVal);
static CHerculesData* NewLC(const TDesC8& aStreamData);
~CHerculesData();
public:
Creates an HBufC8 representation of HBufC8* MarshalDataL() const;
’this’ protected:
Writes ’this’ to the stream void ExternalizeL(RWriteStream& aStream) const;
Initializes ’this’ from the stream void InternalizeL(RReadStream& aStream);

protected:
Constructors omitted for clarity ...
private:
HBufC8* iDes1;
HBufC8* iDes2;
TInt iVal;
};

Fundamentals of Symbian C++ 84


Client Server

Custom Types: C- and R-class Objects


Creates a CHerculesData initialized with the contents of the descriptor parameter.
Used server-side

NewLC CHerculesData* CHerculesData::NewLC(const TDesC8&


aStreamData)
{
CHerculesData* data = new(ELeave) CHerculesData();
CleanupStack::PushL(data);
Open a read stream for the descriptor RDesReadStream stream(aStreamData);
CleanupClosePushL(stream);
data->InternalizeL(stream);
Finished with the stream CleanupStack::PopAndDestroy(&stream);
return (data);
}

Destructor CHerculesData::~CHerculesData()
{
delete iDes1;
delete iDes2;
}

Fundamentals of Symbian C++ 85


Client Server

Custom Types: C- and R-class Objects


Creates and returns a heap descriptor which holds the contents of ’this’
Used client-side

Create a dynamic flat buffer to hold this object’s HBufC8* CHerculesData::MarshalDataL() const
member data {
"Granularity" of dynamic buffer const TInt KExpandSize = 128;
CBufFlat* buf = CBufFlat::NewL(KExpandSize);
CleanupStack::PushL(buf);
RBufWriteStream stream(*buf);
CleanupClosePushL(stream);
Write ’this’ to stream ExternalizeL(stream);
CleanupStack::PopAndDestroy(&stream);
Create a heap descriptor from the buffer
HBufC8* des = HBufC8::NewL(buf->Size());
TPtr8 ptr(des->Des());
buf->Read(0, ptr, buf->Size());
Finished with buf
CleanupStack::PopAndDestroy(buf);
Return (transferring ownership to caller)
return (des);
}

Fundamentals of Symbian C++ 86


Client Server

Custom Types: C- and R-class Objects


Writes ’this’ to aStream for marshalling from client-side to server-side

void CHerculesData::ExternalizeL(RWriteStream& aStream) const


{
if (iDes1)
{
Write iDes1 to the stream aStream << *iDes1;
}
else
{
or a NULL descriptor aStream << KNullDesC8;
}
if (iDes2)
{
Write iDes2 to the stream aStream << *iDes2;
}
else
{
or a NULL descriptor aStream << KNullDesC8;
}
Write iVal to the stream aStream.WriteInt32L(iVal);
}

Fundamentals of Symbian C++ 87


Client Server

Custom Types: C- and R-class Objects


For reconstructing CHerculesData from stream server-side
Initializes ’this’ with the contents of aStream

void CHerculesData::InternalizeL(RReadStream& aStream)


{
Limits each to max 1024 bytes const TInt KMaxReadSize = 1024;
Read iDes1 iDes1 = HBufC8::NewL(aStream, KMaxReadSize);
Read iDes2 iDes2 = HBufC8::NewL(aStream, KMaxReadSize);
Read iVal iVal = aStream.ReadInt32L();
}

Fundamentals of Symbian C++ 88


Client Server

Custom Types: C- and R-class Objects


Request passes a C class object
Client-side

TInt RHerculesSession::SlayErymanthianBoar(const CHerculesData& aData)


{
HBufC8* dataDes=NULL;
TRAPD(r, dataDes = aData.MarshalDataL());
if (dataDes)
{
TPtr8 ptr(dataDes->Des());
TIpcArgs args(&ptr);
r = SendReceive(ESlayErymanthianBoar, args);
delete dataDes;
}
return (r);
}

Fundamentals of Symbian C++ 89


Client Server

Read–Write Request Parameters

Client-request submission mustdifferentiate between


•  non-modifiable arguments passing constant data to the server
•  and modifiable arguments used to retrieve data from it

Request which passes a read/write integer to the server


•  Using TPckg to descriptorize the TInt& (i.e. modifiable reference)

TInt RHerculesSession::CaptureCeryneianHind(TInt& aCaptureCount)


{
TPckg<TInt> countBuf(aCaptureCount);
TIpcArgs args(&countBuf);
return (SendReceive(ECaptureCeryneianHind,args));
}

Fundamentals of Symbian C++ 90


Client Server

Asynchronous Requests

It is important that the client-side data passed to an


asynchronous request must not be stack-based
•  Because the server may not process the incoming request data until
some arbitrary time after the client issued the request

The parameters must remain in existence until that time


•  They cannot exist on the stack in case the client-side function which
submitted the request returns (since this will destroy the stack frame)

This applies not just to read–write parameters


•  But also to read-only parameters since the request may be queued
for the server
•  That is - it may not be read until after the SendReceive() call has
completed

Fundamentals of Symbian C++ 91


Client Server

Asynchronous Requests

The client must also submit a TRequestStatus object for


notification of request completion
•  In this example, the TIpcArgs parameter is constructed empty
because no parameter data accompanies the request

void RHerculesSession::CleanAugeanStables(TRequestStatus& aStatus)


{
SendReceive(ECleanAugeanStables, TIpcArgs(), aStatus);
}

Fundamentals of Symbian C++ 92


Client Server

Impact of the Client–Server Framework

•  Understand the potential impact on run-time speed from using a


client–server session and differentiate between circumstances
where it is useful or necessary and where it is inefficient
•  Recognize scenarios where an implementation which uses client
subsessions with the server would be recommended
•  Understand the impact of the context switch required when making
a client–server request, and the best way to manage
communication between a client and a server to maximize run-time
efficiency

Fundamentals of Symbian C++ 93


Client Server

Session Creation Overhead

A client can have multiple sessions with a server


•  Each client session also consumes resources in both the server
and the kernel

For each open client session


•  The kernel creates and stores an object to represent it
•  The server creates an object of its CSession2-derived class

Additionally
•  Each session carries a run-time speed and memory overhead in
the kernel and the client- and server-side threads

Fundamentals of Symbian C++ 94


Client Server

Session Creation Overhead

The number of sessions created by a client should be


minimized

Instead of creating and opening multiple sessions on


demand
•  Client code should try to share a single session

For efficiency - where multiple sessions are required


•  A client–server implementation may provide a subsession
class
•  This reduces the expense of multiple open sessions

Fundamentals of Symbian C++ 95


Client Server

Session Creation Overhead

To use a subsession
•  A client must open a session with the server as normal
•  This can then be used to create subsessions which consume fewer
resources and can be created more quickly

A typical client subsession implementation derives from


RSubSessionBase
•  In a similar manner to a client session which derives from
RSessionBase

The implementing class


•  Provides simple wrapper functions to hide the details of the
subsession

Fundamentals of Symbian C++ 96


Client Server

Session Creation Overhead

A good example of the use of subsessions is RFile


•  Which derives from RSubSessionBase
•  Is a subsession of an RFs client session to the file server
•  An RFile object represents a subsession for access to individual
files

Fundamentals of Symbian C++ 97


Client Server

Performance Overhead

It is important to be aware of the system performance


implications when using the client–server model

The amount of data transferred between the client and server


does not cause much of an overhead
•  But the frequency with which the communication occurs does

The main overhead is due to


•  A thread context switch which is necessary to pass a message
from the client thread to the server thread
•  And another to switch back again

A process context switch is also involved if the client and


server threads are running in different processes

Fundamentals of Symbian C++ 98


Client Server

Performance Overhead

A context switch between threads


•  Stores the state of the running thread, overwriting it with the
previous state of the replacing thread

If the client and server threads are in the same process


•  The thread context switch stores the processor registers for the
threads

If the client and server are running in two separate processes -


in addition to the thread context switch
•  The process context (the address space accessible to the thread)
must be stored and restored
•  The MMU must remap the memory chunks for each process
•  On some hardware this means that the cache must be flushed

Fundamentals of Symbian C++ 99


Client Server

Performance Overhead

The exact nature of the overhead of a thread or


process context switch
•  Depends on the hardware in question

Inter-thread data transfer between threads running


in separate processes can also have an overhead
•  As an area of data belonging to the client must be
mapped into the server’s address space

Fundamentals of Symbian C++ 100


Client Server

Performance Improvements

For performance reasons, when transferring data between the


client and server
•  It is preferable where possible to transfer a large amount of data in
a single transaction rather than to perform a number of server
accesses

There is no upper limit on the amount of data that can be


transferred between the client and server
•  But saving context-switching time must be balanced against the
memory cost associated with storing and managing large blocks of
request data

Fundamentals of Symbian C++ 101


Client Server

Performance Improvements

For example
•  Components that frequently transfer data to or from the file system
generally do not use direct file system access methods such as
RFile::Read() or RFile::Write()

They tend to use the stream store APIs


•  These API methods have been optimized to access the file server
efficiently

When storing data to file, the stream APIs buffer it on the client
side
•  And pass it to the file server in one block
(Rather than passing individual chunks of data as it is received)

Fundamentals of Symbian C++ 102


Client Server

Performance Improvements

RWriteStream
•  Uses a client-side buffer to hold the data it is passed
•  Only accesses the file server to write it to file when the buffer is full
•  Or if the owner of the stream calls CommitL()

RReadStream
•  Pre-fills a buffer from the source file when it is created
•  When the stream owner wishes to access data from the file the
stream uses this buffer to retrieve the portions of data required
(Rather than calling the file server to access the file directly)

Fundamentals of Symbian C++ 103


Client Server

Performance Improvements

When writing code which uses a server, such as the file server
•  It is always worth considering how to make server access most efficient

For example, the file server provides functions to acquire individual


directory entries in the file system
•  But it is often more efficient to read an entire set of entries and scan them
client-side...
•  ...rather than call across the process boundary multiple times to iterate
through a set of directory entries

A well-programmed client implementation will present a high-level API


so that one transaction performs several actions server-side

Fundamentals of Symbian C++ 104


Client Server

Client–Server Framework

  Client–Server Data Transfer (Example)

  Impact of the Client–Server Framework

Fundamentals of Symbian C++ 105

You might also like