Symbian3/SDK/Source/GUID-2F4B2A69-9B92-52BE-9A1A-FDA501579CE5.dita
changeset 0 89d6a7a84779
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Symbian3/SDK/Source/GUID-2F4B2A69-9B92-52BE-9A1A-FDA501579CE5.dita	Thu Jan 21 18:18:20 2010 +0000
@@ -0,0 +1,180 @@
+<?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-2F4B2A69-9B92-52BE-9A1A-FDA501579CE5" xml:lang="en"><title>Using
+Message Queue</title><shortdesc>This topic explains the operations that can be performed using
+message queue.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
+<ul>
+<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>
+<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>
+<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>
+<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>
+<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>
+<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>
+</ul>
+<section id="GUID-D08DB507-7AFD-5ADD-B785-03BF01BE758D"><title>Creating &amp;
+opening a queue</title> <p>A global queue is created by calling <codeph>CreateGlobal()</codeph> on
+a handle object, while a local queue is created by calling <codeph>CreateLocal()</codeph>.</p> <p>A
+global queue is opened by calling <codeph>OpenGlobal()</codeph> on a handle
+object, passing a queue name.</p> <p>All the memory used by the queue is allocated
+when the queue is created, so it is possible for the call that creates a queue
+to fail with out of memory. The queue is deleted when the last open handle
+on it is closed.</p> <p><b> Creating
+a global named queue</b> </p> <codeblock id="GUID-C70F3600-6198-5DFE-AFA9-2A9366472ED9" xml:space="preserve">_LIT(KGLobalName, "GlobalMessageQueue");
+const TInt KNumberOfSlots = 5;
+const TInt KMessageLength = 16;
+RMsgQueueBase queue;
+TInt ret = queue.CreateGlobal(KGLobalName, KNumberOfSlots, KMessageLength, EOwnerProcess);
+        </codeblock> <p>This code fragment creates a global named message
+queue called <codeph>GlobalMessageQueue</codeph> with 5 slots, each capable
+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
+practice</i>, you would use the template class <xref href="GUID-5195B8D1-851E-3BEE-A72D-1841C0937300.dita"><apiname>RMsgQueue</apiname></xref>.
+For example:</p> <codeblock id="GUID-79040227-DE95-58AB-BC2E-105085AF89F3" xml:space="preserve">class TMyClass
+    {
+public:
+    TInt iA;
+    TInt iB;
+    TInt iC;
+    TInt iD;
+    }
+
+_LIT(KGLobalName, "GlobalMessageQueue");
+const TInt KNumberOfSlots = 5;
+RMsgQueue&lt;TMyClass&gt; queue;
+TInt ret = queue.CreateGlobal(KGLobalName, KNumberOfSlots, EOwnerProcess);
+        </codeblock> <p>The length of the message is the length of the templated
+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;
+RMsgQueueBase queue;
+TInt ret = queue.CreateLocal(KNumberOfSlots, RMsgQueueBase::KMaxLength);
+        </codeblock> <p>This creates a local queue with 2 message slots that
+have the maximum possible message size. <i>In practice</i>, you would use
+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");
+RMsgQueueBase queue;
+TInt messageSize = 0;
+TInt ret = queue.OpenGlobal(KGLobalName1);
+If (ret == KErrNone)
+    {
+    messageSize = queue.MessageSize();
+    }
+        </codeblock> <p>This opens the global named message queue called <codeph>GlobalMessageQueue</codeph>.
+The message size used within this queue is queried by calling <codeph>MessageSize()</codeph>.
+If the queue does not exist <codeph>OpenGlobal()</codeph> returns <codeph>KErrNotFound</codeph>.</p> <p>Note
+that using an illegal message size when writing to, or reading from, a queue
+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
+than the base class <xref href="GUID-2DCEE7F5-9EA3-3546-8779-7299318176E2.dita"><apiname>RMsgQueueBase</apiname></xref> to avoid this problem.</p> </section>
+<section id="GUID-2C05D532-9353-5E83-A8D8-1EACB9D44662"><title>Sending a message
+to the queue</title> <p>A message is sent to a message queue by calling <codeph>Send()</codeph> or <codeph>SendBlocking()</codeph> on
+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
+the queue is full, <codeph>SendBlocking()</codeph> waits until there is space
+in the queue.</p> <p>The following example creates a global named queue, and
+sends 2 integer to values to it. The first call to <codeph>Send()</codeph> returns
+an error if the queue is full, the call to <codeph>SendBlocking()</codeph> waits
+until there is space in the queue. Although the example code uses the base
+class <xref href="GUID-2DCEE7F5-9EA3-3546-8779-7299318176E2.dita"><apiname>RMsgQueueBase</apiname></xref>, <i>in practice</i> you would use the
+templated class <xref href="GUID-5195B8D1-851E-3BEE-A72D-1841C0937300.dita"><apiname>RMsgQueue</apiname></xref>, to avoid the risk of passing
+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");
+RMsgQueueBase mqueue;
+
+TInt ret = mqueue.CreateGlobal(KGLobalName1, 1, sizeof (TInt));
+if (ret == KErrNone)
+    {
+    TInt src = 45;
+    ret = mqueue.Send(&amp;src, sizeof (TInt));
+    TBool full = (ret == KErrOverflow);
+
+    //blocking send
+    src = 32;
+    mqueue.SendBlocking(&amp;src, sizeof(TInt));
+    mqueue.Close();
+    }
+        </codeblock> </section>
+<section id="GUID-683F69D9-CC59-5F8C-A65B-E69D98737A96"><title>Receiving a
+message from the queue</title> <p>A message is received from a message queue
+by calling <codeph>Receive()</codeph> or <codeph>ReceiveBlocking()</codeph> on
+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
+the queue is empty, <codeph>ReceiveBlocking()</codeph> waits until there is
+data in the queue.</p> <p>The following example opens a global named queue
+and receives 2 integer values from it. The first call to <codeph>Receive()</codeph> returns
+an error if the queue is empty, the call to <codeph>ReceiveBlocking()</codeph> waits
+until there is data available in the queue. Note also that using the base
+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
+raising panics if the length specified is not the same as the message size
+specified when the queue was originally created, or if the pointer to the
+receive buffer is not a valid address.</p> <codeblock id="GUID-9EBE78E0-F7A4-5764-A182-DF7C87E18026" xml:space="preserve">_LIT(KGLobalName, "GlobalMessageQueue");
+RMsgQueueBase mqueue;
+
+TInt ret = mqueue.OpenGlobal(KGLobalName1);
+if (ret == KErrNone)
+    {
+    TInt data;
+    ret = mqueue.Receive(&amp;data, sizeof (TInt));
+    TBool empty = (ret == KErrUnderflow);
+
+    //blocking receive
+    mqueue.ReceiveBlocking(&amp;data, sizeof(TInt));
+    mqueue.Close();
+    }
+        </codeblock> </section>
+<section id="GUID-1647018E-85C2-58DC-A97A-F90580D9D4E2"><title> Waiting for
+messages or space</title> <p>It is possible to be notified:</p> <ul>
+<li id="GUID-C67C5535-12C4-5AA6-9E84-947CF4FABCA9"><p>when a queue has messages,
+by calling <codeph>NotifyDataAvailable()</codeph> on the base class <xref href="GUID-2DCEE7F5-9EA3-3546-8779-7299318176E2.dita"><apiname>RMsgQueueBase</apiname></xref> </p> </li>
+<li id="GUID-307D0C2E-CF65-5572-8BE9-9F9A63B331FC"><p>when a queue has space
+for more messages, by calling <codeph>NotifySpaceAvailable()</codeph> on the
+base class <xref href="GUID-2DCEE7F5-9EA3-3546-8779-7299318176E2.dita"><apiname>RMsgQueueBase</apiname></xref>.</p> </li>
+</ul> <p>Note that the calling <codeph>NotifyDataAvailable()</codeph> when
+such a request is still outstanding or calling <codeph>NotifySpaceAvailable()</codeph> when
+such a request is already outstanding, results in the calling thread being
+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;
+mqueue.NotifyDataAvailable(stat);
+mqueue.CancelDataAvailable();
+User::WaitForRequest(stat);
+        </codeblock> </section>
+<section id="GUID-A5EABF21-FB2C-5B91-9007-40B4FBE04269"><title>Querying a
+Queue’s Size</title> <p>The size of the message slot can be queried by calling <codeph>MessageSize()</codeph> on
+the handle. This is useful when a queue is opened, as the calling thread is
+panicked if the size is out of range on a <codeph>Send()</codeph> or if the
+size is not exact on a <codeph>Receive().</codeph> </p> </section>
+<section id="GUID-72033282-9E2F-5E8E-8D78-1B8F6DF42D82"><title>An example
+of a type specific queue</title> <p>The size of the message is the size of
+the type, and has the same restrictions as the base class, namely it must
+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
+    {
+public:
+    TTemplateTestData();
+    TTemplateTestData(TInt a, TUint b, TUint8 c, TBool d, TInt e);
+
+public:
+    TInt first;
+    TUint second;
+    TUint8 third;
+    TBool fourth;
+    TInt fifth;
+    };
+
+    {
+    ....
+    RMsgQueue&lt;TTemplateTestData&gt; templateQueue;
+
+    TTemplateTestData ch(1,2,3,ETrue,4);
+    TTemplateTestData ch2;
+    TTemplateTestData ch3;
+
+    templateQueue.CreateLocal(12); 
+    templateQueue.Send(ch);
+    templateQueue.Receive(ch2);
+    ....
+    templateQueue.Close();
+    ...
+    }
+        </codeblock> <p>Note, the size of the type (i.e. the size of the message)
+must be a multiple of 4 bytes.</p> </section>
+</conbody></concept>
\ No newline at end of file