Adaptation/GUID-178E140F-BB15-5A82-99A6-D1BC0E11E018.dita
author Graeme Price <GRAEME.PRICE@NOKIA.COM>
Fri, 15 Oct 2010 14:32:18 +0100
changeset 15 307f4279f433
permissions -rw-r--r--
Initial contribution of the Adaptation Documentation.

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
<!-- This component and the accompanying materials are made available under the terms of the License 
"Eclipse Public License v1.0" which accompanies this distribution, 
and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
<!-- Initial Contributors:
    Nokia Corporation - initial contribution.
Contributors: 
-->
<!DOCTYPE concept
  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="GUID-178E140F-BB15-5A82-99A6-D1BC0E11E018" xml:lang="en"><title>Kernel-side
Messages</title><shortdesc>Kernel-side messages are a means of communication between Symbian
platform threads executing kernel-side code. </shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
<p>Typically, they are used by device drivers to communicate between a client
thread, usually a user thread, and a kernel thread running the actual device
driver code. </p>
<p>The mechanism consists of a message, containing data, and a queue that
is associated with a DFC. The DFC runs in order to deal with each message. </p>
<p>A kernel-side message is represented by a <xref href="GUID-3FDD1B46-1427-3F1C-99D2-AD8446658E5A.dita"><apiname>TMessageBase</apiname></xref> object,
that allows a single 32-bit argument to be passed, and a single 32-bit return
value. In general, more arguments can be passed by deriving classes from <codeph>TMessageBase</codeph>.
In practice, each Symbian platform thread has a <xref href="GUID-D43CB8FA-C212-3B56-AD16-9F1D69DA7551.dita"><apiname>TThreadMessage</apiname></xref> object
embedded within it. <codeph>TThreadMessage</codeph> is derived from <codeph>TMessageBase</codeph>,
and contains space for 10 extra 32-bit arguments. These objects are used for
communication with device driver threads. </p>
<p>Both <codeph>TMessageBase</codeph> and <codeph>TThreadMessage</codeph> are
defined in <filepath>...\kernel\kernel.h</filepath>, which is exported to <filepath>epoc32\include\kernel</filepath>. </p>
<fig id="GUID-230AECE3-5006-543A-9F4F-088C62E14E6D">
<title>Message threads and queues</title>
<image href="GUID-D8A3C18B-A107-5557-B882-CD6CDD0F0F1D_d0e76208_href.png" placement="inline"/>
</fig>
<p> <xref href="GUID-CAAD5B87-CEE7-30E8-BA6A-08F9407C4C20.dita"><apiname>SDblQueLink</apiname></xref> is simply an object that allows a message
to be linked to another in the form of a doubly-linked list. </p>
<p>The message queue is represented by a <xref href="GUID-382DD935-E9D7-3E00-88B2-B28A89CAD4FB.dita"><apiname>TMessageQue</apiname></xref> object,
which consists of a DFC plus a doubly-linked list of received messages. The
DFC is attached to the receiving thread’s DFC queue and it runs whenever a
message becomes available for processing. </p>
<p> <codeph>TMessageQue</codeph> is defined in <filepath>...include\kernel\kernel.h</filepath>,
which is exported to <filepath>epoc32\include\kernel</filepath>; <codeph>SDblQueLink</codeph> is
defined in <filepath>...\nkern\nklib.h</filepath>, which is exported to <filepath>epoc32\include\nkern</filepath>. </p>
<p>The following shows, in simple terms, the relationship between messages
and the message queues: </p>
<fig id="GUID-2D1F4468-5208-51F1-9E48-B5E9DC44B6B2">
<title>Relationship between messages and message queues</title>
<image href="GUID-DA7751A1-4EC5-5FBA-A42B-E254133A1D82_d0e76254_href.png" placement="inline"/>
</fig>
<p>When a message is sent to the queue, either: </p>
<ul>
<li id="GUID-08445948-588F-512B-BA6C-D641F0DDF572"><p>the message is accepted
immediately, and the receiving thread’s DFC runs. This will happen if the
message queue is ready to receive, which will be the case if the message queue
is empty and the receiving thread has requested the next message. </p> </li>
</ul>
<p>or </p>
<ul>
<li id="GUID-BF81268D-31A4-50D6-A43A-F2C4556B367F"><p>the message is placed
on the delivered message queue, and the DFC does not run. This will happen
if there are other messages queued ahead of this one or if the receiving thread
has not (yet) requested another message. </p> </li>
</ul>
<p>A kernel-side message may be in one of three states at any time: </p>
<ul>
<li id="GUID-C9CF11B5-0B76-5F8A-87CC-75DF595F657E"><p>FREE - represented by
the <xref href="GUID-3FDD1B46-1427-3F1C-99D2-AD8446658E5A.dita#GUID-3FDD1B46-1427-3F1C-99D2-AD8446658E5A/GUID-BBF5D5BD-BC64-3EC8-82F4-A7A3EB1FF043"><apiname>TMessageBase::EFree</apiname></xref> enum value. This indicates that
the message is not currently in use. </p> </li>
<li id="GUID-924008AC-58F7-5979-95FA-EC11EC5B5D07"><p>DELIVERED - represented
by the <xref href="GUID-3FDD1B46-1427-3F1C-99D2-AD8446658E5A.dita#GUID-3FDD1B46-1427-3F1C-99D2-AD8446658E5A/GUID-828BA7EF-8962-3CEA-B322-7D92E368957B"><apiname>TMessageBase::EDelivered</apiname></xref> enum value. This indicates
that the message is attached to a message queue but is not currently in use
by the receiving thread. It may be removed from the queue and discarded with
no ill effects on the receiving thread. The client thread pointer may not
be used while the message is in this state. </p> </li>
<li id="GUID-57807061-A767-59A4-9D10-6A08A06DA214"><p>ACCEPTED - represented
by the <xref href="GUID-3FDD1B46-1427-3F1C-99D2-AD8446658E5A.dita#GUID-3FDD1B46-1427-3F1C-99D2-AD8446658E5A/GUID-D4BB85D9-DE00-3BD8-8A9A-4D40C031A94C"><apiname>TMessageBase::EAccepted</apiname></xref> enum value. This indicates
that the message is not attached to a message queue but is currently in use
by the receiving thread. The message may not be discarded. </p> </li>
</ul>
<p>Transitions between these states, including adding the message to, and
removing the message from a message queue, occur under the protection of the
global <xref href="GUID-382DD935-E9D7-3E00-88B2-B28A89CAD4FB.dita#GUID-382DD935-E9D7-3E00-88B2-B28A89CAD4FB/GUID-1134F81A-4427-3B7E-8BF3-1F2DB6698261"><apiname>TMessageQue::MsgLock</apiname></xref> fast mutex. The use of a mutex
is necessary to avoid queue corruption, for example, when multiple threads
are sending messages to the same message queue at the same time. The use of
a fast mutex means that message passing operations may only be invoked from
a thread context. </p>
<p>Kernel-side messages may be sent either synchronously or asynchronously.
Each <xref href="GUID-3FDD1B46-1427-3F1C-99D2-AD8446658E5A.dita"><apiname>TMessageBase</apiname></xref> object contains an <xref href="GUID-22982E51-E746-37CB-9672-97B58C2672BF.dita"><apiname>NFastSemaphore</apiname></xref> on
which the sending thread will wait after sending a synchronous message. The
semaphore is signalled by the receiving thread after the message has been
processed and the completion code has been written in. The sending thread
is then released and picks up the return code. The <codeph>NFastSemaphore</codeph> also
contains a pointer to the sending <xref href="GUID-187D314F-1115-3671-AC46-37AEC5DFB2AC.dita"><apiname>NThread</apiname></xref>; this serves
to identify the sending thread and is therefore set up for both synchronous
and asynchronous message send. Note that this pointer is reference counted
- the access count of the originating <xref href="GUID-38D1534C-AA01-33AF-9937-CDD818A85F97.dita"><apiname>DThread</apiname></xref> is incremented
when the message is sent. This prevents the sending <codeph>DThread</codeph> object
disappearing if the thread terminates unexpectedly. When the message is completed
the extra access is removed asynchronously - the thread completing the message
will not need to delete the <codeph>DThread</codeph> itself. This is done
to avoid unpredictable execution times for message completion. Also note that
even messages sent asynchronously must be completed; this is required to set
the message state back to FREE and to remove the access count from the sending
thread. </p>
<p>The <xref href="GUID-D43CB8FA-C212-3B56-AD16-9F1D69DA7551.dita"><apiname>TThreadMessage</apiname></xref> objects embedded in Symbian platform
thread control blocks, <xref href="GUID-38D1534C-AA01-33AF-9937-CDD818A85F97.dita"><apiname>DThread</apiname></xref> objects, are always sent
synchronously - this ensures that one message per thread will always suffice.
In addition, these messages are cancelled if the corresponding thread terminates.
Cancelling an ACCEPTED message has no effect, but cancelling a DELIVERED message
will remove the message from the queue and also remove the access count held
by the message on the sending thread. Hence the sending thread pointer should
only be used by the receiving thread if the message is in the ACCEPTED state. </p>
</conbody></concept>