Symbian3/SDK/Source/GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF.dita
changeset 0 89d6a7a84779
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Symbian3/SDK/Source/GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF.dita	Thu Jan 21 18:18:20 2010 +0000
@@ -0,0 +1,422 @@
+<?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-FE910347-7CC1-5241-B443-88AD3F5A96EF" xml:lang="en"><title>Using
+Publish and Subscribe</title><shortdesc>This topic explains the operations that can be performed using
+publish and subscribe.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
+<ul>
+<li id="GUID-AE4CAAA9-9EB2-5AA0-ACB9-073EAAA9D2C1"><p> <xref href="GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF.dita#GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF/GUID-383A6127-FCE0-5B0E-BD54-3AAFEB097AC9">Creating and closing a handle to a property</xref>  </p> </li>
+<li id="GUID-3F0622EC-8490-585A-8CA8-09A3925E842E"><p> <xref href="GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF.dita#GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF/GUID-75BCC783-8DA2-519F-9E4A-B597BDC90E79">Defining a property</xref>  </p> </li>
+<li id="GUID-D6C38BDD-02CD-5D9F-8872-DD621D58DB85"><p> <xref href="GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF.dita#GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF/GUID-D942B400-37F8-5C02-AC95-2BD195D3348D">Deleting a property</xref>  </p> </li>
+<li id="GUID-ED1DE72F-9111-51A5-9AB2-D7112D947465"><p> <xref href="GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF.dita#GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF/GUID-3B2B63B8-EB2A-5845-A738-A10012A7C896">Publishing a property value</xref>  </p> </li>
+<li id="GUID-360F7C12-4909-52EE-9468-E40A3ABC944A"><p> <xref href="GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF.dita#GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF/GUID-CD731DD7-E833-5C67-9B90-0357C9552450">Retrieving a property value</xref>  </p> </li>
+<li id="GUID-57301501-34C1-5BE1-9AAB-36F97DBCF5C0"><p> <xref href="GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF.dita#GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF/GUID-A17955E9-FC4C-5FF9-8CC4-2425931E1DEB">Subscribing to, and unsubscribing from, a property</xref>  </p> </li>
+<li id="GUID-AAA0B4BB-4B01-5F5E-8617-6D02B36DCEF2"><p> <xref href="GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF.dita#GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF/GUID-EF683969-CED9-5986-938D-3D887E3B39BD">Usage patterns</xref>  </p> </li>
+<li id="GUID-E2D3A0BE-1FD9-5B56-928A-4265940E0DEA"><p> <xref href="GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF.dita#GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF/GUID-2B022BE9-2004-54E8-962E-5AB38DDC4222">Making efficient use of the user side API</xref>  </p> </li>
+</ul>
+<section id="GUID-383A6127-FCE0-5B0E-BD54-3AAFEB097AC9"><title>Creating and
+closing a handle to a property</title> <p>Some property operations require
+a reference to the property to be established first. This is done using the <xref href="GUID-C4776034-D190-3FC4-AF45-C7F195093AC3.dita#GUID-C4776034-D190-3FC4-AF45-C7F195093AC3/GUID-3F65DD85-6061-3370-9618-ECC0400323D1"><apiname>RProperty::Attach()</apiname></xref> member
+function. After a call to this function, the <xref href="GUID-C4776034-D190-3FC4-AF45-C7F195093AC3.dita"><apiname>RProperty</apiname></xref> object
+acts like a standard handle to a kernel resource. When this handle is no longer
+required, it can be released in the standard way by calling the inherited <xref href="GUID-727D2B62-09A9-3CBC-AB6F-591E52EC68EB.dita#GUID-727D2B62-09A9-3CBC-AB6F-591E52EC68EB/GUID-4B2775FD-AB61-3850-86C5-780CE8C97573"><apiname>RHandleBase::Close()</apiname></xref> member
+function. </p> <p>Note that releasing the handle does not cause the property
+to disappear. This only happens if the property is deleted. </p> <p>Note also
+that it is quite legitimate to attach to a property that has not been defined,
+and in this case no error will be returned either. This enables the lazy definition
+of properties as used in some of the usage patterns. </p> <codeblock id="GUID-A836D288-8511-5CED-B3F9-42B60569EE27" xml:space="preserve">// attach to the ‘counter’ property
+RProperty counter;
+TInt r=counter.Attach(KMyPropertyCat,EMyPropertyName,EOwnerThread);
+User::LeaveIfError(r);
+
+// use the counter object...
+
+// when finished, release the handle
+counter.Close();
+    </codeblock> </section>
+<section id="GUID-75BCC783-8DA2-519F-9E4A-B597BDC90E79"><title>Defining a
+property</title> <p>A property is defined using the <xref href="GUID-C4776034-D190-3FC4-AF45-C7F195093AC3.dita#GUID-C4776034-D190-3FC4-AF45-C7F195093AC3/GUID-58C54D2A-91E0-359B-AA31-69C6C4050173"><apiname>RProperty::Define()</apiname></xref> function,
+specifying the attributes of that property. </p> <p>A property does not need
+to be defined before it can be accessed. This supports programming patterns
+where both publishers and subscribers may define the property. Note, however
+that for security reasons, there are restrictions on the category that can
+be used when defining a property; see <xref href="GUID-DAF86036-CC40-5F26-9F15-2F2093F59C03.dita">security
+issues</xref> for more information. </p> <p>Once defined, a property persists
+in the kernel until the system reboots, or the property is explicitly deleted.
+Its lifetime is not tied to that of the thread or process that originally
+defined it. This means that, when defining a property, it is important to
+check the return code from the call <codeph>RProperty::Define()</codeph> to
+deal with the possibility that the property has previously been defined, but
+not deleted. </p> <p>The following code shows the definition of two properties: </p> <codeblock id="GUID-1F3E05DB-A34B-5D79-8512-52CAD86B0A2D" xml:space="preserve">enum TMyPropertyKeys={EMyPropertyCounter,EMyPropertyName};
+
+static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
+static _LIT_SECURITY_POLICY_C1(KPowerMgmtPolicy,ECapabilityPowerMgmt);
+
+// define first property to be integer type
+TInt r=RProperty::Define(EMyPropertyCounter,RProperty::EInt,KAllowAllPolicy,KPowerMgmtPolicy);
+if (r!=KErrAlreadyExists)
+    {
+    User::LeaveIfError(r);
+    }
+
+// define second property to be a byte array, allocating 100 bytes
+r=RProperty::Define(EMyPropertyName,RProperty::EByteArray,KAllowAllPolicy,KPowerMgmtPolicy,100);
+if (r!=KErrAlreadyExists)
+    {
+    User::LeaveIfError(r);
+    }
+. . .
+    </codeblock> <p>Once defined, a property value can change, but the property
+type cannot. Byte-array type properties can also change length provided the
+length does not exceed the maximum value of 512 bytes. The limit on the size
+of a property ensures some limit on RAM usage. </p> <p>The API allows byte-array
+and Unicode text type properties to be pre-allocated when they are defined.
+This means that the time taken to set the values is bounded. However, if the
+length of these property types subsequently increases, then memory allocation
+may take place, and no guarantees can then be made on the time taken to set
+them. </p> <p>There are further <xref href="GUID-DAF86036-CC40-5F26-9F15-2F2093F59C03.dita">security
+issues</xref> to be considered when defining a property. You need to provide
+two security policies - one to govern which processes can publish the property
+value, and the other to govern which processes can retrieve the property value.
+Security policies are instances of <xref href="GUID-81A285F6-3F87-3E77-9426-61BB16BC7109.dita"><apiname>TSecurityPolicy</apiname></xref> objects,
+although for efficiency reasons, you will almost always use the <codeph>_LIT_SECURITY_POLICY_...</codeph> macros
+to generate constant objects that behave like <codeph>TSecurityPolicy</codeph> objects.
+The API reference for <xref href="GUID-81A285F6-3F87-3E77-9426-61BB16BC7109.dita"><apiname>TSecurityPolicy</apiname></xref> provides far more
+detail on this. </p> <p>In this example, all processes will be allowed to
+retrieve the property value, but only those processes having the power management
+system capability (<xref href="GUID-76F4383B-4EA5-391A-A271-A8F65ED77EC0.dita"><apiname>ECapabilityPowerMgmt</apiname></xref>) will be allowed
+to publish the property value. </p> <p>Note that a process that defines a
+property does not have automatic rights of access to that property, other
+than to delete it. If the defining process also wishes to publish and/or subscribe
+to that property, then it must ensure that it satisfies the security policies
+that it itself has put in place when defining the property. </p> </section>
+<section id="GUID-D942B400-37F8-5C02-AC95-2BD195D3348D"><title>Deleting a
+property</title> <p>A defined property is deleted by calling <xref href="GUID-C4776034-D190-3FC4-AF45-C7F195093AC3.dita#GUID-C4776034-D190-3FC4-AF45-C7F195093AC3/GUID-226BC411-A2D2-30D1-BD86-9DDBD855C1E4"><apiname>RProperty::Delete()</apiname></xref>.
+Any outstanding subscriptions for this property will complete with <xref href="GUID-5E653C17-372C-32E1-A1B2-9E69A9991C40.dita"><apiname>KErrNotFound</apiname></xref>.
+Only the process with the correct secure ID is allowed to delete it. </p> <p>For
+example, extending the code fragment introduced above: </p> <codeblock id="GUID-D4CC3017-D17D-5E7C-AC57-0DBD8B789349" xml:space="preserve">enum TMyPropertyKeys={EMyPropertyCounter,EMyPropertyName};
+
+// define first property to be integer type
+TInt r=RProperty::Define(EMyPropertyCounter,RProperty::EInt);
+if (r!=KErrAlreadyExists)
+    {
+    User::LeaveIfError(r);
+    }
+
+// define second property to be a byte array, allocating 100 bytes
+r=RProperty::Define(EMyPropertyName,RProperty::EByteArray,100);
+if (r!=KErrAlreadyExists)
+    {
+    User::LeaveIfError(r);
+    }
+. . .
+
+// much later on
+
+. . .
+// delete the ‘name’ property
+r=RProperty::Delete(EMyPropertyName);
+if (r!=KErrNotFound)
+    {
+    User::LeaveIfError(r);
+    }
+    </codeblock> </section>
+<section id="GUID-3B2B63B8-EB2A-5845-A738-A10012A7C896"><title>Publishing
+a property value</title> <p>A property is published using the <codeph>RProperty::Set()</codeph> family
+of functions. Properties can be published: </p> <ul>
+<li id="GUID-3A136703-587F-55B9-9EE6-EE512845956A"><p>using a previously attached <xref href="GUID-C4776034-D190-3FC4-AF45-C7F195093AC3.dita"><apiname>RProperty</apiname></xref> handle, </p> </li>
+</ul> <p>or </p> <ul>
+<li id="GUID-126B0DC1-D4FC-520C-9583-50E64CBC7B80"><p>by specifying the property
+category and key with the new value. </p> </li>
+</ul> <p>The former mode is guaranteed to have bounded execution time, suitable
+for high-priority, real-time tasks, except when publishing a byte-array property
+that requires the allocation of a larger space for the new value. </p> <p>The
+latter mode offers no real-time guarantees. </p> <p>Property values are written
+atomically. This means that it is not possible for threads reading a property
+to get a garbled value. </p> <p>All outstanding subscriptions for a property
+are completed when the value is published, even if it is exactly the same
+as the existing value. This means that a property can be used as a simple
+broadcast notification service. </p> <p>Publishing a property that is not
+defined is not necessarily a programming error. The <codeph>Set()</codeph> functions
+just return an error. If this is not expected for any particular usage, then
+the error must be checked and processed by the caller. </p> <p>See the code
+fragment in the section <xref href="GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF.dita#GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF/GUID-CD731DD7-E833-5C67-9B90-0357C9552450">Retrieving
+a property value</xref>  </p> </section>
+<section id="GUID-CD731DD7-E833-5C67-9B90-0357C9552450"><title>Retrieving
+a property value</title> <p>The current value of a property is read using
+the <codeph>RProperty::Get()</codeph> family of functions. Properties can
+be retrieved: </p> <ul>
+<li id="GUID-81AD34BF-9A45-5DEE-AD20-AA908F5BF94A"><p>using a previously attached <xref href="GUID-C4776034-D190-3FC4-AF45-C7F195093AC3.dita"><apiname>RProperty</apiname></xref> handle, </p> </li>
+</ul> <p>or </p> <ul>
+<li id="GUID-1163D9F2-BDEA-55E1-B6FB-D9A353F4D53E"><p>by specifying the property
+category and key with the new value. </p> </li>
+</ul> <p>The former mode is guaranteed to have bounded execution time, suitable
+for high-priority, real-time tasks. </p> <p>The latter mode offers no real-time
+guarantees. </p> <p>Property values are read atomically. This means that it
+is not possible for threads reading a property to get a garbled value. </p> <p>Retrieving
+a property that is not defined is not necessarily a programming error. The <codeph>Get()</codeph> functions
+just return an error. If this is not expected for any particular usage, then
+the error must be checked and processed by the caller. </p> <p>Integer properties
+must be accessed using the overloads that take an integer or integer reference
+value, whereas byte-array properties can be accessed using the overloads that
+take a descriptor reference. </p> <p>The following code fragment shows publication
+and retrieval of a property. Note that it uses the idea of attaching to a
+property. Note also that it contains a race condition, especially if another
+thread is executing the same sequence to increment the ‘counter’ value. </p> <codeblock id="GUID-27B8D567-DD92-5FD6-B2E3-AF343C1116B1" xml:space="preserve">const TUid KMyPropertyCat={0x10012345};
+enum TMyPropertyKeys={EMyPropertyCounter,EMyPropertyName};
+
+// attach to the ‘counter’ property
+RProperty counter;
+TInt r=counter.Attach(KMyPropertyCat,EMyPropertyCounter,EOwnerThread);
+User::LeaveIfError(r);
+
+// publish a new name value
+TFileName n;
+RProcess().Filename(n);
+r=RProperty::Set(KMyPropertyCat,EMyPropertyName,n);
+User::LeaveIfError(r);
+
+// retrieve the first 10 characters of the name value
+TBuf&lt;10&gt; name;
+r=RProperty::Get(KMyPropertyCat,EMyPropertyName,name);
+if (r!=KErrOverflow)
+    {
+    User::LeaveIfError(r);
+    }
+
+// retrieve and publish a new value using the attached ‘counter’ property
+TInt count;
+r=counter.Get(count);
+if (r==KErrNone)
+    {
+    r=counter.Set(++count);
+    }
+User::LeaveIfError(r);
+
+// when finised, release the handle
+counter.Close();
+    </codeblock> </section>
+<section id="GUID-A17955E9-FC4C-5FF9-8CC4-2425931E1DEB"><title>Subscribing
+to, and unsubscribing from, a property</title> <p>Subscribing to a property
+is the act of making an asynchronous request to be notified of a change to
+that property. </p> <p>A thread makes a request for notification of a change
+to a property by calling the <xref href="GUID-C4776034-D190-3FC4-AF45-C7F195093AC3.dita#GUID-C4776034-D190-3FC4-AF45-C7F195093AC3/GUID-21A2FEB7-AAF1-3AC0-84B9-AB30E6CFFF99"><apiname>RProperty::Subscribe()</apiname></xref> member
+function on an already attached property object. Only one subscription request
+can be outstanding at any one time for a <xref href="GUID-C4776034-D190-3FC4-AF45-C7F195093AC3.dita"><apiname>RProperty</apiname></xref> instance. </p> <p>An
+outstanding subscription request can be cancelled by calling the <xref href="GUID-C4776034-D190-3FC4-AF45-C7F195093AC3.dita#GUID-C4776034-D190-3FC4-AF45-C7F195093AC3/GUID-326D75D3-9D54-3BD2-8B78-FAD1EEA1A1A5"><apiname>RProperty::Cancel()</apiname></xref> member
+function. This is unsubscribing from the property. </p> <p>Subscribing to
+a property is a single request to be notified when the property is next updated,
+it does not generate an ongoing sequence of notifications for every change
+to that property's value. Neither does it provide the caller with the new
+value. In essence, the act of notification should be interpreted as “Property
+X has changed” rather than “Property X has changed to Y”. This means that
+the new value must be explicitly retrieved, if required. As a result, multiple
+updates may be collapsed into one notification, and subscribers may not have
+visibility of all intermediate values. </p> <p>This might appear to introduce
+a window of opportunity for a subscriber to be out of synchronisation with
+the property value – in particular, if the property is updated again before
+the subscriber thread has had the chance to process the original notification.
+However, a simple programming pattern, outlined in the second example below
+ensures this does not happen. The principle is that, before dealing with a
+subscription completion event, an active object should re-issue the subscription
+request. </p> <p>Note that if the property has not been defined, then a subscription
+request does not complete until the property is subsequently defined and published.
+Note that the request will complete with <xref href="GUID-213DE05E-24F7-3E94-9B35-F4A72B3EBFD8.dita"><apiname>KErrPermissionDenied</apiname></xref> if
+the subscribing process does not have sufficient capability as defined by
+the <xref href="GUID-81A285F6-3F87-3E77-9426-61BB16BC7109.dita"><apiname>TSecurityPolicy</apiname></xref> object supplied by the process defining
+the property. </p> <p>If the property is already defined, then the request
+completes immediately with <xref href="GUID-213DE05E-24F7-3E94-9B35-F4A72B3EBFD8.dita"><apiname>KErrPermissionDenied</apiname></xref> if the
+subscribing process does not have sufficient capability. </p> <codeblock id="GUID-F8AB71E9-1EB4-5EFB-9D1F-38625F782BA6" xml:space="preserve">const TUid KMyPropertyCat={0x10012345};
+enum TMyPropertyKeys={EMyPropertyCounter,EMyPropertyName};
+
+// attach to the ‘counter’ property
+RProperty counter;
+TInt r=counter.Attach(KMyPropertyCat,EMyPropertyCounter,EOwnerThread);
+User::LeaveIfError(r);
+
+// wait for the previously attached ‘counter’ property to be updated
+TRequestStatus s;
+counter.Subscribe(s);
+User::WaitForRequest(s);
+
+// Notification complete, retrieve the counter value.
+TInt count;
+counter.Get(count);
+. . .
+    </codeblock> <codeblock id="GUID-5E726809-0060-5E76-A0D5-4AE73155724A" xml:space="preserve">const TUid KMyPropertyCat={0x10012345};
+enum TMyPropertyKeys={EMyPropertyCounter,EMyPropertyName};
+
+// Active object that tracks changes to the ‘name’ property
+class CPropertyWatch : public CActive
+    {
+    enum {EPriority=0};
+public:
+    static CPropertyWatch* NewL();
+private:
+    CPropertyWatch();
+    void ConstructL();
+    ~CPropertyWatch();
+    void RunL();
+    void DoCancel();
+private:
+    RProperty iProperty;
+    };
+
+CPropertyWatch* CPropertyWatch::NewL()
+    {
+    CPropertyWatch* me=new(ELeave) CPropertyWatch;
+    CleanupStack::PushL(me);
+    me-&gt;ConstructL();
+    CleanupStack::Pop(me);
+    return me;
+    }
+
+CPropertyWatch::CPropertyWatch()
+    :CActive(EPriority)
+    {}
+
+void CPropertyWatch::ConstructL()
+    {
+    User::LeaveIfError(iProperty.Attach(KMyPropertyCat,KMyPropertyName));
+    CActiveScheduler::Add(this);
+    // initial subscription and process current property value
+    RunL();
+    }
+
+CPropertyWatch::~CPropertyWatch()
+    {
+    Cancel();
+    iProperty.Close();
+    }
+
+void CPropertyWatch::DoCancel()
+    {
+    iProperty.Cancel();
+    }
+
+void CPropertyWatch::RunL()
+    {
+    // resubscribe before processing new value to prevent missing updates
+    iProperty.Subscribe(iStatus);
+    SetActive();
+
+    // property updated, get new value
+    TFileName n;
+    if (iProperty.Get(n)==KErrNotFound)
+        {
+        // property deleted, do necessary actions here...
+        NameDeleted();
+        }
+    else
+        {
+        // use new value ...
+        NameChanged(n);
+        }
+    }
+    </codeblock> </section>
+<section id="GUID-EF683969-CED9-5986-938D-3D887E3B39BD"><title>Usage patterns</title> <p>There
+are three usage patterns that can easily be identified, labelled as: standard
+state, pure event distribution, and speculative publishing. </p> <p id="GUID-0DFB902E-FCE1-52CF-8523-C7AE7B6768CE"><b>Standard state</b> </p> <p>This
+pattern is used for events and state that are known to be used widely in the
+system. Examples of this might be battery level and signal strength, which
+are important in every phone. </p> <p>The publisher calls <xref href="GUID-C4776034-D190-3FC4-AF45-C7F195093AC3.dita#GUID-C4776034-D190-3FC4-AF45-C7F195093AC3/GUID-58C54D2A-91E0-359B-AA31-69C6C4050173"><apiname>RProperty::Define()</apiname></xref> to
+create the appropriate property. For byte array or text properties, a size
+sufficient for all possible values should be reserved. An error of <xref href="GUID-D1D25122-F2B8-3C78-8599-84905BFD47B8.dita"><apiname>KErrAlreadyExists</apiname></xref> should
+be ignored. The publisher then publishes the property values as, and when,
+appropriate. If the <codeph>RProperty::Set()</codeph> call fails, this should
+be treated as a serious error, since it indicates that important system state
+is not getting through. Appropriate action might include panicking or rebooting
+the system. Subscribers will use <xref href="GUID-C4776034-D190-3FC4-AF45-C7F195093AC3.dita#GUID-C4776034-D190-3FC4-AF45-C7F195093AC3/GUID-21A2FEB7-AAF1-3AC0-84B9-AB30E6CFFF99"><apiname>RProperty::Subscribe()</apiname></xref> to
+request notification, and <codeph>RProperty::Get()</codeph> to retrieve the
+property value on notification. </p> <p>The memory to store the property value
+will be permanently allocated, even if it turns out that no-one in the system
+needs that value. This does ensure that the value can always be published,
+even if the system is in an out of memory situation. For this reason, this
+approach should be limited to widely used and important state. The <xref href="GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF.dita#GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF/GUID-01254366-696D-598F-9670-6A178F4E69F7">Speculative publishing</xref> pattern offers an approach for dealing with
+less important state. </p> <p id="GUID-F2A60E64-C279-5E08-8AA8-52DF1EEA32BD"><b>Pure event distribution</b> </p> <p>This
+pattern is used when events need to be distributed, not values. </p> <p>The
+publisher of the event simply uses an integer property, and calls RProperty::Set()
+with any value. Even if the value of the property is not changed by this operation,
+all subscribers will be notified that a Set() has occurred, and by implication
+that the related event has occurred. </p> <p>Subscribers will be able to detect
+that an event has occurred, but will get no other information. The minimum
+possible memory is wasted on storage for the dummy value. </p> <p id="GUID-01254366-696D-598F-9670-6A178F4E69F7"><b>Speculative publishing</b> </p> <p>This
+pattern is used when it is not known whether a value will be of interest to
+others or not. Unlike the <xref href="GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF.dita#GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF/GUID-0DFB902E-FCE1-52CF-8523-C7AE7B6768CE">standard
+state</xref> pattern, the publisher of the event does not call <xref href="GUID-C4776034-D190-3FC4-AF45-C7F195093AC3.dita#GUID-C4776034-D190-3FC4-AF45-C7F195093AC3/GUID-58C54D2A-91E0-359B-AA31-69C6C4050173"><apiname>RProperty::Define()</apiname></xref> to
+create the property. Instead, it simply calls <codeph>RProperty::Set()</codeph> as
+appropriate, and ignores any <xref href="GUID-5E653C17-372C-32E1-A1B2-9E69A9991C40.dita"><apiname>KErrNotFound</apiname></xref> error. </p> <p>When
+other code in the system, i.e. a potential subscriber, is interested in the
+state, it calls <xref href="GUID-C4776034-D190-3FC4-AF45-C7F195093AC3.dita#GUID-C4776034-D190-3FC4-AF45-C7F195093AC3/GUID-58C54D2A-91E0-359B-AA31-69C6C4050173"><apiname>RProperty::Define()</apiname></xref> to create the property
+and allocate the memory for the value. An error of <xref href="GUID-D1D25122-F2B8-3C78-8599-84905BFD47B8.dita"><apiname>KErrAlreadyExists</apiname></xref> should
+be ignored, as this only indicates that some other code in the system is also
+interested in the value and has already created the property. </p> <p>The
+subscriber then calls <xref href="GUID-C4776034-D190-3FC4-AF45-C7F195093AC3.dita#GUID-C4776034-D190-3FC4-AF45-C7F195093AC3/GUID-21A2FEB7-AAF1-3AC0-84B9-AB30E6CFFF99"><apiname>RProperty::Subscribe()</apiname></xref> and <codeph>RProperty::Get()</codeph> as
+usual to interact with the property. On the first <codeph>Get()</codeph>,
+the subscriber may retrieve the property default value (zero, or a zero length
+descriptor). This must be substituted with a sensible default value for the
+property in question. </p> <p>Using this pattern, no memory is wasted on properties
+that have no subscribers, while the publisher code is simpler as there is
+no need for configuration as to which properties to publish. </p> <p>The publisher,
+however, wastes some time attempting to publish unneeded values, but this
+should not be an issue unless the value is very frequently updated. </p> <p>Where
+events are published very infrequently, the subscriber could have a dummy
+value for a long time, until the next publish event updates the value. Often
+this is not a problem as a default value can be substituted. For example a
+full/empty indicator for a battery level, none for signal strength etc. This
+pattern is unlikely to be useful if there is no suitable default value. </p> </section>
+<section id="GUID-2B022BE9-2004-54E8-962E-5AB38DDC4222"><title>Making efficient
+use of the user side API</title> <p>While the Publish and Subscribe API, as
+represented by <xref href="GUID-C4776034-D190-3FC4-AF45-C7F195093AC3.dita"><apiname>RProperty</apiname></xref> is designed to be efficient, there
+are certain usage patterns that can improve performance. </p> <p><b>Use
+the attached version of the API calls if possible</b> </p> <p>If you intend
+to call <codeph>Set()</codeph> or <codeph>Get()</codeph> repeatedly, it is
+preferable to use the attached forms of the calls. The attached forms are
+the ones that do not take a UID/Key parameter, and that can only be called
+after calling <xref href="GUID-C4776034-D190-3FC4-AF45-C7F195093AC3.dita#GUID-C4776034-D190-3FC4-AF45-C7F195093AC3/GUID-3F65DD85-6061-3370-9618-ECC0400323D1"><apiname>RProperty::Attach()</apiname></xref>. The attached variants
+are constant time operations, and execute much faster than the corresponding
+unattached versions. </p> <p><b>Only
+preallocate space if the publishing is time critical</b> </p> <p>For byte-array
+and text properties, it is possible to pre-allocate space for the data. Doing
+this results in <codeph>Set()</codeph> operations that do not exceed the preallocated
+space, avoiding the need to do a memory allocation. However, if the data is
+shorter than the reserved space, the excess is wasted. Since <codeph>Set()</codeph> automatically
+extends the data area if needed, then the only reason to pre-allocate space
+is if the <codeph>Set()</codeph> operation has to be real-time, i.e. has to
+have known execution time. </p> <p><b>Always
+consider using Speculative Publishing</b> </p> <p>Even in situations where
+the <xref href="GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF.dita#GUID-FE910347-7CC1-5241-B443-88AD3F5A96EF/GUID-0DFB902E-FCE1-52CF-8523-C7AE7B6768CE">Standard
+State</xref> pattern may seem appropriate, speculative publishing may be a
+better choice, specially for low-level components that know little about how
+they are used or what the wider system configuration may be. The onus is then
+on the UI/Policy layer to ensure that the appropriate properties are defined
+early on in device boot according to policy rules it can define. This ensures
+that the policy layers in the system maintain control and can implement a
+wide variety of policies. </p> <p>Standard state is only relevant for properties
+that are essential to every Symbian device. Battery level probably falls into
+this category, signal strength may well not. </p> <p><b>Define the expected update frequency</b> </p> <p>When a property is changed,
+all subscribers are notified. This leads to their threads running to service
+the notification. If a property changes value frequently, it would be wasteful
+for subscribers to perform substantial processing for each notification. </p> <p>Take
+a property representing signal strength as an example. Potentially, this could
+be updated several times a second. If a change in value were only used to
+update the UI signal bar, it would not be harmful. However, if it were used
+by many entities for serious processing (e.g. polling for email, sending unsent
+SMSes, re-connecting to the internet), then such frequent updates would have
+a severe effect on battery life. </p> <p>Nevertheless, it is obviously desirable
+for many parts of a phone OS to know about the state of network coverage,
+and to take appropriate action. In cases like this, it may be worth the publisher
+defining multiple properties with associated update characteristics. For example,
+raw signal strength (updated &gt; 1 time/sec), periodic signal strength (updated
+once every 10s) and network coverage (updated only when moving between some
+signal and none). Each subscriber can then monitor the appropriate notification
+and so reduce the number of threads that run when the underlying value changes. </p> </section>
+</conbody></concept>
\ No newline at end of file