contentmgmt/contentaccessfwfordrm/engineering/dox/AsyncSendReceive.dox
changeset 108 ca9a0fc2f082
parent 102 deec7e509f66
equal deleted inserted replaced
102:deec7e509f66 108:ca9a0fc2f082
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // An agent plugin may have to service an asynchronous request, for example when
       
    15 // <code>ContentAccess::CAgentManager::NotifyStatusChange()</code> is called.
       
    16 // If the agent plugin must make an asynchronous SendReceive() call to service the request
       
    17 // then it must be careful to ensure that any memory that is passed as an argument
       
    18 // in the call is still valid when the agent server that receives the call processes
       
    19 // and uses the memory.
       
    20 // There are two ways that this can be achieved:
       
    21 // <hr>
       
    22 // If the agent plugin cannot guarantee that a variable to be passed in the asynchronous
       
    23 // SendReceive() call will still be in scope when the agent server comes to access and use
       
    24 // it then the agent plugin should store a local heap copy of the data and pass this
       
    25 // in the call instead. It is the responsibility of the agent plugin to maintain this heap 
       
    26 // memory and delete it when appropriate. Depending on how and when the agent server uses 
       
    27 // the memory, it may be safe to delete the memory after the asynchronous call has 
       
    28 // been accepted, or not until the asynchronous request has completed.
       
    29 // For example, an agent plugin could implement the API <code>ContentAccess::CAgentManager::NotifyStatusChange()</code> 
       
    30 // as illustrated below. Note that for this API the agent plugin can make no assumption about the 
       
    31 // scope of the descriptor passed to aURI. 
       
    32 // void CTestAgentManager::NotifyStatusChange(const TDesC& aURI, TEventMask aMask, TRequestStatus& aStatus)
       
    33 // HBufC* uri = aURI.Alloc();
       
    34 // if(uri)
       
    35 // // store the heap variable in a local array
       
    36 // iAsyncDataArray.Append(uri); // takes ownership of uri
       
    37 // SendReceive(EManagerNotifyStatusChange, TIpcArgs(uri,aMask),aStatus);		
       
    38 // <hr>
       
    39 // Alternatively, the agent plugin can use the variables that are in scope at the time of the 
       
    40 // asynchronous SendReceive() call if it makes a synchronous SendReceive() call afterwards,
       
    41 // within the same function scope, as illustrated below. The synchronous message can 
       
    42 // be a 'no operation' in the agent server.
       
    43 // void CTestAgentManager::NotifyStatusChange(const TDesC& aURI, TEventMask aMask, TRequestStatus& aStatus)
       
    44 // SendReceive(EManagerNotifyStatusChange, TIpcArgs(&aURI,aMask),aStatus);
       
    45 // // this call doesn't have to be immediately after the asynchronous call, but within this function
       
    46 // SendReceive(ENoOp,TIpcArgs(NULL));
       
    47 // The synchronous call causes the message queue to be flushed into the agent server before the thread returns from the 
       
    48 // function and unwinds the call stack. The intention is that the agent server will only complete the second (synchronous) 
       
    49 // message after receiving and doing initial processing of the first (asynchronous) message, which may include, for 
       
    50 // example, reading the uri descriptor. 
       
    51 // However, an obvious disadvantage of this pattern is that it incurs a second IPC call, and so may degrade performance.<br>
       
    52 // Moreover, there are several caveats which must hold true in order for the pattern to work:
       
    53 // 1. The kernel delivers messages in the order that they are sent (this is currently true).<br>
       
    54 // 2. The agent server is guaranteed to finish processing the first message before completing the second message.<br>
       
    55 // This requires understanding of the agent server implementation.<br>
       
    56 // 3. After initial processing of the first (asynchronous) message the agent server does not need to 
       
    57 // access the memory supplied in the message again. This requires understanding of the agent server implementation.<br>
       
    58 // 4. The synchronous call is a request that has no effect on the state of the agent server - a 'no operation'
       
    59 // may or may not be possible.
       
    60 // <b> 
       
    61 // For these reasons, this pattern should only be used as a last resort - for example, if the agent plugin cannot store member data in its class for compatibility reasons.
       
    62 // <b>
       
    63 // 
       
    64 //
       
    65 
       
    66 /**
       
    67  @page CAFAsyncSendReceive Making an asynchronous SendReceive() call in an agent plugin
       
    68  - @ref StoreLocalCopy
       
    69  - @ref SyncSendReceive
       
    70  @section StoreLocalCopy Storing a local heap copy of transient data
       
    71  @code
       
    72  @endcode
       
    73  @section SyncSendReceive Following the asynchronous call with a synchronous call
       
    74  @code
       
    75  @endcode
       
    76 */