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