|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-178E140F-BB15-5A82-99A6-D1BC0E11E018" xml:lang="en"><title>Kernel-side |
|
13 Messages</title><shortdesc>Kernel-side messages are a means of communication between Symbian |
|
14 platform threads executing kernel-side code. </shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
15 <p>Typically, they are used by device drivers to communicate between a client |
|
16 thread, usually a user thread, and a kernel thread running the actual device |
|
17 driver code. </p> |
|
18 <p>The mechanism consists of a message, containing data, and a queue that |
|
19 is associated with a DFC. The DFC runs in order to deal with each message. </p> |
|
20 <p>A kernel-side message is represented by a <xref href="GUID-3FDD1B46-1427-3F1C-99D2-AD8446658E5A.dita"><apiname>TMessageBase</apiname></xref> object, |
|
21 that allows a single 32-bit argument to be passed, and a single 32-bit return |
|
22 value. In general, more arguments can be passed by deriving classes from <codeph>TMessageBase</codeph>. |
|
23 In practice, each Symbian platform thread has a <xref href="GUID-D43CB8FA-C212-3B56-AD16-9F1D69DA7551.dita"><apiname>TThreadMessage</apiname></xref> object |
|
24 embedded within it. <codeph>TThreadMessage</codeph> is derived from <codeph>TMessageBase</codeph>, |
|
25 and contains space for 10 extra 32-bit arguments. These objects are used for |
|
26 communication with device driver threads. </p> |
|
27 <p>Both <codeph>TMessageBase</codeph> and <codeph>TThreadMessage</codeph> are |
|
28 defined in <filepath>...\kernel\kernel.h</filepath>, which is exported to <filepath>epoc32\include\kernel</filepath>. </p> |
|
29 <fig id="GUID-230AECE3-5006-543A-9F4F-088C62E14E6D"> |
|
30 <title>Message threads and queues</title> |
|
31 <image href="GUID-D8A3C18B-A107-5557-B882-CD6CDD0F0F1D_d0e76208_href.png" placement="inline"/> |
|
32 </fig> |
|
33 <p> <xref href="GUID-CAAD5B87-CEE7-30E8-BA6A-08F9407C4C20.dita"><apiname>SDblQueLink</apiname></xref> is simply an object that allows a message |
|
34 to be linked to another in the form of a doubly-linked list. </p> |
|
35 <p>The message queue is represented by a <xref href="GUID-382DD935-E9D7-3E00-88B2-B28A89CAD4FB.dita"><apiname>TMessageQue</apiname></xref> object, |
|
36 which consists of a DFC plus a doubly-linked list of received messages. The |
|
37 DFC is attached to the receiving thread’s DFC queue and it runs whenever a |
|
38 message becomes available for processing. </p> |
|
39 <p> <codeph>TMessageQue</codeph> is defined in <filepath>...include\kernel\kernel.h</filepath>, |
|
40 which is exported to <filepath>epoc32\include\kernel</filepath>; <codeph>SDblQueLink</codeph> is |
|
41 defined in <filepath>...\nkern\nklib.h</filepath>, which is exported to <filepath>epoc32\include\nkern</filepath>. </p> |
|
42 <p>The following shows, in simple terms, the relationship between messages |
|
43 and the message queues: </p> |
|
44 <fig id="GUID-2D1F4468-5208-51F1-9E48-B5E9DC44B6B2"> |
|
45 <title>Relationship between messages and message queues</title> |
|
46 <image href="GUID-DA7751A1-4EC5-5FBA-A42B-E254133A1D82_d0e76254_href.png" placement="inline"/> |
|
47 </fig> |
|
48 <p>When a message is sent to the queue, either: </p> |
|
49 <ul> |
|
50 <li id="GUID-08445948-588F-512B-BA6C-D641F0DDF572"><p>the message is accepted |
|
51 immediately, and the receiving thread’s DFC runs. This will happen if the |
|
52 message queue is ready to receive, which will be the case if the message queue |
|
53 is empty and the receiving thread has requested the next message. </p> </li> |
|
54 </ul> |
|
55 <p>or </p> |
|
56 <ul> |
|
57 <li id="GUID-BF81268D-31A4-50D6-A43A-F2C4556B367F"><p>the message is placed |
|
58 on the delivered message queue, and the DFC does not run. This will happen |
|
59 if there are other messages queued ahead of this one or if the receiving thread |
|
60 has not (yet) requested another message. </p> </li> |
|
61 </ul> |
|
62 <p>A kernel-side message may be in one of three states at any time: </p> |
|
63 <ul> |
|
64 <li id="GUID-C9CF11B5-0B76-5F8A-87CC-75DF595F657E"><p>FREE - represented by |
|
65 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 |
|
66 the message is not currently in use. </p> </li> |
|
67 <li id="GUID-924008AC-58F7-5979-95FA-EC11EC5B5D07"><p>DELIVERED - represented |
|
68 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 |
|
69 that the message is attached to a message queue but is not currently in use |
|
70 by the receiving thread. It may be removed from the queue and discarded with |
|
71 no ill effects on the receiving thread. The client thread pointer may not |
|
72 be used while the message is in this state. </p> </li> |
|
73 <li id="GUID-57807061-A767-59A4-9D10-6A08A06DA214"><p>ACCEPTED - represented |
|
74 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 |
|
75 that the message is not attached to a message queue but is currently in use |
|
76 by the receiving thread. The message may not be discarded. </p> </li> |
|
77 </ul> |
|
78 <p>Transitions between these states, including adding the message to, and |
|
79 removing the message from a message queue, occur under the protection of the |
|
80 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 |
|
81 is necessary to avoid queue corruption, for example, when multiple threads |
|
82 are sending messages to the same message queue at the same time. The use of |
|
83 a fast mutex means that message passing operations may only be invoked from |
|
84 a thread context. </p> |
|
85 <p>Kernel-side messages may be sent either synchronously or asynchronously. |
|
86 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 |
|
87 which the sending thread will wait after sending a synchronous message. The |
|
88 semaphore is signalled by the receiving thread after the message has been |
|
89 processed and the completion code has been written in. The sending thread |
|
90 is then released and picks up the return code. The <codeph>NFastSemaphore</codeph> also |
|
91 contains a pointer to the sending <xref href="GUID-187D314F-1115-3671-AC46-37AEC5DFB2AC.dita"><apiname>NThread</apiname></xref>; this serves |
|
92 to identify the sending thread and is therefore set up for both synchronous |
|
93 and asynchronous message send. Note that this pointer is reference counted |
|
94 - the access count of the originating <xref href="GUID-38D1534C-AA01-33AF-9937-CDD818A85F97.dita"><apiname>DThread</apiname></xref> is incremented |
|
95 when the message is sent. This prevents the sending <codeph>DThread</codeph> object |
|
96 disappearing if the thread terminates unexpectedly. When the message is completed |
|
97 the extra access is removed asynchronously - the thread completing the message |
|
98 will not need to delete the <codeph>DThread</codeph> itself. This is done |
|
99 to avoid unpredictable execution times for message completion. Also note that |
|
100 even messages sent asynchronously must be completed; this is required to set |
|
101 the message state back to FREE and to remove the access count from the sending |
|
102 thread. </p> |
|
103 <p>The <xref href="GUID-D43CB8FA-C212-3B56-AD16-9F1D69DA7551.dita"><apiname>TThreadMessage</apiname></xref> objects embedded in Symbian platform |
|
104 thread control blocks, <xref href="GUID-38D1534C-AA01-33AF-9937-CDD818A85F97.dita"><apiname>DThread</apiname></xref> objects, are always sent |
|
105 synchronously - this ensures that one message per thread will always suffice. |
|
106 In addition, these messages are cancelled if the corresponding thread terminates. |
|
107 Cancelling an ACCEPTED message has no effect, but cancelling a DELIVERED message |
|
108 will remove the message from the queue and also remove the access count held |
|
109 by the message on the sending thread. Hence the sending thread pointer should |
|
110 only be used by the receiving thread if the message is in the ACCEPTED state. </p> |
|
111 </conbody></concept> |