Symbian3/PDK/Source/GUID-2F4B2A69-9B92-52BE-9A1A-FDA501579CE5.dita
changeset 1 25a17d01db0c
child 3 46218c8b8afa
equal deleted inserted replaced
0:89d6a7a84779 1:25a17d01db0c
       
     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-2F4B2A69-9B92-52BE-9A1A-FDA501579CE5" xml:lang="en"><title>Using
       
    13 Message Queue</title><shortdesc>This topic explains the operations that can be performed using
       
    14 message queue.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    15 <ul>
       
    16 <li id="GUID-47D01156-47CE-5E19-9B0D-222E05851555"><p><xref href="GUID-2F4B2A69-9B92-52BE-9A1A-FDA501579CE5.dita#GUID-2F4B2A69-9B92-52BE-9A1A-FDA501579CE5/GUID-D08DB507-7AFD-5ADD-B785-03BF01BE758D">Creating &amp; opening a queue</xref> </p> </li>
       
    17 <li id="GUID-4CFC9AD9-5303-597D-A339-26064DDA459F"><p><xref href="GUID-2F4B2A69-9B92-52BE-9A1A-FDA501579CE5.dita#GUID-2F4B2A69-9B92-52BE-9A1A-FDA501579CE5/GUID-2C05D532-9353-5E83-A8D8-1EACB9D44662">Sending data to the queue</xref> </p> </li>
       
    18 <li id="GUID-D7A7CB34-16CF-545C-927D-99AF3011C6E7"><p><xref href="GUID-2F4B2A69-9B92-52BE-9A1A-FDA501579CE5.dita#GUID-2F4B2A69-9B92-52BE-9A1A-FDA501579CE5/GUID-683F69D9-CC59-5F8C-A65B-E69D98737A96">Receiving a message from the queue</xref> </p> </li>
       
    19 <li id="GUID-3A517EE0-2B17-5EEF-BFEE-FF98FD1BE9BF"><p><xref href="GUID-2F4B2A69-9B92-52BE-9A1A-FDA501579CE5.dita#GUID-2F4B2A69-9B92-52BE-9A1A-FDA501579CE5/GUID-1647018E-85C2-58DC-A97A-F90580D9D4E2">Waiting for messages or space</xref> </p> </li>
       
    20 <li id="GUID-5379B30A-4E56-5C7E-A7E3-44C8E5592946"><p><xref href="GUID-2F4B2A69-9B92-52BE-9A1A-FDA501579CE5.dita#GUID-2F4B2A69-9B92-52BE-9A1A-FDA501579CE5/GUID-A5EABF21-FB2C-5B91-9007-40B4FBE04269">Querying a Queue’s Size</xref> </p> </li>
       
    21 <li id="GUID-6FD43EA9-4E52-5F60-AD10-314964015F9E"><p><xref href="GUID-2F4B2A69-9B92-52BE-9A1A-FDA501579CE5.dita#GUID-2F4B2A69-9B92-52BE-9A1A-FDA501579CE5/GUID-72033282-9E2F-5E8E-8D78-1B8F6DF42D82">An example of a type specific queue</xref> </p> </li>
       
    22 </ul>
       
    23 <section id="GUID-D08DB507-7AFD-5ADD-B785-03BF01BE758D"><title>Creating &amp;
       
    24 opening a queue</title> <p>A global queue is created by calling <codeph>CreateGlobal()</codeph> on
       
    25 a handle object, while a local queue is created by calling <codeph>CreateLocal()</codeph>.</p> <p>A
       
    26 global queue is opened by calling <codeph>OpenGlobal()</codeph> on a handle
       
    27 object, passing a queue name.</p> <p>All the memory used by the queue is allocated
       
    28 when the queue is created, so it is possible for the call that creates a queue
       
    29 to fail with out of memory. The queue is deleted when the last open handle
       
    30 on it is closed.</p> <p><b> Creating
       
    31 a global named queue</b> </p> <codeblock id="GUID-C70F3600-6198-5DFE-AFA9-2A9366472ED9" xml:space="preserve">_LIT(KGLobalName, "GlobalMessageQueue");
       
    32 const TInt KNumberOfSlots = 5;
       
    33 const TInt KMessageLength = 16;
       
    34 RMsgQueueBase queue;
       
    35 TInt ret = queue.CreateGlobal(KGLobalName, KNumberOfSlots, KMessageLength, EOwnerProcess);
       
    36         </codeblock> <p>This code fragment creates a global named message
       
    37 queue called <codeph>GlobalMessageQueue</codeph> with 5 slots, each capable
       
    38 of holding a message of size 16 bytes. Note that we have explicitly used <xref href="GUID-2DCEE7F5-9EA3-3546-8779-7299318176E2.dita"><apiname>RMsgQueueBase</apiname></xref>. <i>In
       
    39 practice</i>, you would use the template class <xref href="GUID-5195B8D1-851E-3BEE-A72D-1841C0937300.dita"><apiname>RMsgQueue</apiname></xref>.
       
    40 For example:</p> <codeblock id="GUID-79040227-DE95-58AB-BC2E-105085AF89F3" xml:space="preserve">class TMyClass
       
    41     {
       
    42 public:
       
    43     TInt iA;
       
    44     TInt iB;
       
    45     TInt iC;
       
    46     TInt iD;
       
    47     }
       
    48 
       
    49 _LIT(KGLobalName, "GlobalMessageQueue");
       
    50 const TInt KNumberOfSlots = 5;
       
    51 RMsgQueue&lt;TMyClass&gt; queue;
       
    52 TInt ret = queue.CreateGlobal(KGLobalName, KNumberOfSlots, EOwnerProcess);
       
    53         </codeblock> <p>The length of the message is the length of the templated
       
    54 class, which in this example is also 16.</p> <p><b>Creating a local message queue</b> </p> <codeblock id="GUID-139E6A88-4F52-5036-AF75-2B3CB91802F0" xml:space="preserve">const TInt KNumberOfSlots = 2;
       
    55 RMsgQueueBase queue;
       
    56 TInt ret = queue.CreateLocal(KNumberOfSlots, RMsgQueueBase::KMaxLength);
       
    57         </codeblock> <p>This creates a local queue with 2 message slots that
       
    58 have the maximum possible message size. <i>In practice</i>, you would use
       
    59 the template class <xref href="GUID-5195B8D1-851E-3BEE-A72D-1841C0937300.dita"><apiname>RMsgQueue</apiname></xref> rather than the base class <xref href="GUID-2DCEE7F5-9EA3-3546-8779-7299318176E2.dita"><apiname>RMsgQueueBase</apiname></xref>.</p> <p><b>Opening a named global queue</b> </p> <codeblock id="GUID-9DCB3D58-0690-50BD-A650-DD78FBFA6447" xml:space="preserve">_LIT(KGLobalName, "GlobalMessageQueue");
       
    60 RMsgQueueBase queue;
       
    61 TInt messageSize = 0;
       
    62 TInt ret = queue.OpenGlobal(KGLobalName1);
       
    63 If (ret == KErrNone)
       
    64     {
       
    65     messageSize = queue.MessageSize();
       
    66     }
       
    67         </codeblock> <p>This opens the global named message queue called <codeph>GlobalMessageQueue</codeph>.
       
    68 The message size used within this queue is queried by calling <codeph>MessageSize()</codeph>.
       
    69 If the queue does not exist <codeph>OpenGlobal()</codeph> returns <codeph>KErrNotFound</codeph>.</p> <p>Note
       
    70 that using an illegal message size when writing to, or reading from, a queue
       
    71 is a programming error. <i>In practice</i>, you would use the templated class <xref href="GUID-5195B8D1-851E-3BEE-A72D-1841C0937300.dita"><apiname>RMsgQueue</apiname></xref> rather
       
    72 than the base class <xref href="GUID-2DCEE7F5-9EA3-3546-8779-7299318176E2.dita"><apiname>RMsgQueueBase</apiname></xref> to avoid this problem.</p> </section>
       
    73 <section id="GUID-2C05D532-9353-5E83-A8D8-1EACB9D44662"><title>Sending a message
       
    74 to the queue</title> <p>A message is sent to a message queue by calling <codeph>Send()</codeph> or <codeph>SendBlocking()</codeph> on
       
    75 the message queue handle. <codeph>Send()</codeph> returns the error code <xref href="GUID-F9E0EF8B-4EF5-3E35-811A-00B8F9CCF2FA.dita"><apiname>KErrOverflow</apiname></xref> if
       
    76 the queue is full, <codeph>SendBlocking()</codeph> waits until there is space
       
    77 in the queue.</p> <p>The following example creates a global named queue, and
       
    78 sends 2 integer to values to it. The first call to <codeph>Send()</codeph> returns
       
    79 an error if the queue is full, the call to <codeph>SendBlocking()</codeph> waits
       
    80 until there is space in the queue. Although the example code uses the base
       
    81 class <xref href="GUID-2DCEE7F5-9EA3-3546-8779-7299318176E2.dita"><apiname>RMsgQueueBase</apiname></xref>, <i>in practice</i> you would use the
       
    82 templated class <xref href="GUID-5195B8D1-851E-3BEE-A72D-1841C0937300.dita"><apiname>RMsgQueue</apiname></xref>, to avoid the risk of passing
       
    83 an invalid length, message size, or an invalid data pointer.</p> <codeblock id="GUID-870BFC97-AB6A-5F44-BE3B-BFE2D979CF15" xml:space="preserve">_LIT(KGLobalName, "GlobalMessageQueue");
       
    84 RMsgQueueBase mqueue;
       
    85 
       
    86 TInt ret = mqueue.CreateGlobal(KGLobalName1, 1, sizeof (TInt));
       
    87 if (ret == KErrNone)
       
    88     {
       
    89     TInt src = 45;
       
    90     ret = mqueue.Send(&amp;src, sizeof (TInt));
       
    91     TBool full = (ret == KErrOverflow);
       
    92 
       
    93     //blocking send
       
    94     src = 32;
       
    95     mqueue.SendBlocking(&amp;src, sizeof(TInt));
       
    96     mqueue.Close();
       
    97     }
       
    98         </codeblock> </section>
       
    99 <section id="GUID-683F69D9-CC59-5F8C-A65B-E69D98737A96"><title>Receiving a
       
   100 message from the queue</title> <p>A message is received from a message queue
       
   101 by calling <codeph>Receive()</codeph> or <codeph>ReceiveBlocking()</codeph> on
       
   102 the message queue handle. <codeph>Receive()</codeph> returns the error code <xref href="GUID-3673F75F-655F-3561-BD56-F7E1C6980810.dita"><apiname>KErrUnderflow</apiname></xref> if
       
   103 the queue is empty, <codeph>ReceiveBlocking()</codeph> waits until there is
       
   104 data in the queue.</p> <p>The following example opens a global named queue
       
   105 and receives 2 integer values from it. The first call to <codeph>Receive()</codeph> returns
       
   106 an error if the queue is empty, the call to <codeph>ReceiveBlocking()</codeph> waits
       
   107 until there is data available in the queue. Note also that using the base
       
   108 class <xref href="GUID-2DCEE7F5-9EA3-3546-8779-7299318176E2.dita"><apiname>RMsgQueueBase</apiname></xref> rather than the templated class <xref href="GUID-5195B8D1-851E-3BEE-A72D-1841C0937300.dita"><apiname>RMsgQueue</apiname></xref> risks
       
   109 raising panics if the length specified is not the same as the message size
       
   110 specified when the queue was originally created, or if the pointer to the
       
   111 receive buffer is not a valid address.</p> <codeblock id="GUID-9EBE78E0-F7A4-5764-A182-DF7C87E18026" xml:space="preserve">_LIT(KGLobalName, "GlobalMessageQueue");
       
   112 RMsgQueueBase mqueue;
       
   113 
       
   114 TInt ret = mqueue.OpenGlobal(KGLobalName1);
       
   115 if (ret == KErrNone)
       
   116     {
       
   117     TInt data;
       
   118     ret = mqueue.Receive(&amp;data, sizeof (TInt));
       
   119     TBool empty = (ret == KErrUnderflow);
       
   120 
       
   121     //blocking receive
       
   122     mqueue.ReceiveBlocking(&amp;data, sizeof(TInt));
       
   123     mqueue.Close();
       
   124     }
       
   125         </codeblock> </section>
       
   126 <section id="GUID-1647018E-85C2-58DC-A97A-F90580D9D4E2"><title> Waiting for
       
   127 messages or space</title> <p>It is possible to be notified:</p> <ul>
       
   128 <li id="GUID-C67C5535-12C4-5AA6-9E84-947CF4FABCA9"><p>when a queue has messages,
       
   129 by calling <codeph>NotifyDataAvailable()</codeph> on the base class <xref href="GUID-2DCEE7F5-9EA3-3546-8779-7299318176E2.dita"><apiname>RMsgQueueBase</apiname></xref> </p> </li>
       
   130 <li id="GUID-307D0C2E-CF65-5572-8BE9-9F9A63B331FC"><p>when a queue has space
       
   131 for more messages, by calling <codeph>NotifySpaceAvailable()</codeph> on the
       
   132 base class <xref href="GUID-2DCEE7F5-9EA3-3546-8779-7299318176E2.dita"><apiname>RMsgQueueBase</apiname></xref>.</p> </li>
       
   133 </ul> <p>Note that the calling <codeph>NotifyDataAvailable()</codeph> when
       
   134 such a request is still outstanding or calling <codeph>NotifySpaceAvailable()</codeph> when
       
   135 such a request is already outstanding, results in the calling thread being
       
   136 panicked</p> <p>Notification requests can be cancelled by calling <codeph>CancelDataAvailable()</codeph> or <codeph>CancelDataAvailable()</codeph> respectively.</p> <codeblock id="GUID-960DCF78-0849-59B7-ADF4-95F24EC5B987" xml:space="preserve">TRequestStatus stat;
       
   137 mqueue.NotifyDataAvailable(stat);
       
   138 mqueue.CancelDataAvailable();
       
   139 User::WaitForRequest(stat);
       
   140         </codeblock> </section>
       
   141 <section id="GUID-A5EABF21-FB2C-5B91-9007-40B4FBE04269"><title>Querying a
       
   142 Queue’s Size</title> <p>The size of the message slot can be queried by calling <codeph>MessageSize()</codeph> on
       
   143 the handle. This is useful when a queue is opened, as the calling thread is
       
   144 panicked if the size is out of range on a <codeph>Send()</codeph> or if the
       
   145 size is not exact on a <codeph>Receive().</codeph> </p> </section>
       
   146 <section id="GUID-72033282-9E2F-5E8E-8D78-1B8F6DF42D82"><title>An example
       
   147 of a type specific queue</title> <p>The size of the message is the size of
       
   148 the type, and has the same restrictions as the base class, namely it must
       
   149 be greater than 0, a multiple of 4 bytes and not greater than <xref href="GUID-2DCEE7F5-9EA3-3546-8779-7299318176E2.dita#GUID-2DCEE7F5-9EA3-3546-8779-7299318176E2/GUID-2E514C07-6917-3DDD-A2E6-CD09A9CD2A6D"><apiname>RMsgQueueBase::KMaxLength</apiname></xref>.</p> <codeblock id="GUID-88F3E2B6-F4B7-53B1-A275-C4AB6BA53448" xml:space="preserve">class TTemplateTestData
       
   150     {
       
   151 public:
       
   152     TTemplateTestData();
       
   153     TTemplateTestData(TInt a, TUint b, TUint8 c, TBool d, TInt e);
       
   154 
       
   155 public:
       
   156     TInt first;
       
   157     TUint second;
       
   158     TUint8 third;
       
   159     TBool fourth;
       
   160     TInt fifth;
       
   161     };
       
   162 
       
   163     {
       
   164     ....
       
   165     RMsgQueue&lt;TTemplateTestData&gt; templateQueue;
       
   166 
       
   167     TTemplateTestData ch(1,2,3,ETrue,4);
       
   168     TTemplateTestData ch2;
       
   169     TTemplateTestData ch3;
       
   170 
       
   171     templateQueue.CreateLocal(12); 
       
   172     templateQueue.Send(ch);
       
   173     templateQueue.Receive(ch2);
       
   174     ....
       
   175     templateQueue.Close();
       
   176     ...
       
   177     }
       
   178         </codeblock> <p>Note, the size of the type (i.e. the size of the message)
       
   179 must be a multiple of 4 bytes.</p> </section>
       
   180 </conbody></concept>