os/security/contentmgmt/contentaccessfwfordrm/engineering/dox/AsyncSendReceive.dox
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/security/contentmgmt/contentaccessfwfordrm/engineering/dox/AsyncSendReceive.dox	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,76 @@
     1.4 +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// An agent plugin may have to service an asynchronous request, for example when
    1.18 +// <code>ContentAccess::CAgentManager::NotifyStatusChange()</code> is called.
    1.19 +// If the agent plugin must make an asynchronous SendReceive() call to service the request
    1.20 +// then it must be careful to ensure that any memory that is passed as an argument
    1.21 +// in the call is still valid when the agent server that receives the call processes
    1.22 +// and uses the memory.
    1.23 +// There are two ways that this can be achieved:
    1.24 +// <hr>
    1.25 +// If the agent plugin cannot guarantee that a variable to be passed in the asynchronous
    1.26 +// SendReceive() call will still be in scope when the agent server comes to access and use
    1.27 +// it then the agent plugin should store a local heap copy of the data and pass this
    1.28 +// in the call instead. It is the responsibility of the agent plugin to maintain this heap 
    1.29 +// memory and delete it when appropriate. Depending on how and when the agent server uses 
    1.30 +// the memory, it may be safe to delete the memory after the asynchronous call has 
    1.31 +// been accepted, or not until the asynchronous request has completed.
    1.32 +// For example, an agent plugin could implement the API <code>ContentAccess::CAgentManager::NotifyStatusChange()</code> 
    1.33 +// as illustrated below. Note that for this API the agent plugin can make no assumption about the 
    1.34 +// scope of the descriptor passed to aURI. 
    1.35 +// void CTestAgentManager::NotifyStatusChange(const TDesC& aURI, TEventMask aMask, TRequestStatus& aStatus)
    1.36 +// HBufC* uri = aURI.Alloc();
    1.37 +// if(uri)
    1.38 +// // store the heap variable in a local array
    1.39 +// iAsyncDataArray.Append(uri); // takes ownership of uri
    1.40 +// SendReceive(EManagerNotifyStatusChange, TIpcArgs(uri,aMask),aStatus);		
    1.41 +// <hr>
    1.42 +// Alternatively, the agent plugin can use the variables that are in scope at the time of the 
    1.43 +// asynchronous SendReceive() call if it makes a synchronous SendReceive() call afterwards,
    1.44 +// within the same function scope, as illustrated below. The synchronous message can 
    1.45 +// be a 'no operation' in the agent server.
    1.46 +// void CTestAgentManager::NotifyStatusChange(const TDesC& aURI, TEventMask aMask, TRequestStatus& aStatus)
    1.47 +// SendReceive(EManagerNotifyStatusChange, TIpcArgs(&aURI,aMask),aStatus);
    1.48 +// // this call doesn't have to be immediately after the asynchronous call, but within this function
    1.49 +// SendReceive(ENoOp,TIpcArgs(NULL));
    1.50 +// The synchronous call causes the message queue to be flushed into the agent server before the thread returns from the 
    1.51 +// function and unwinds the call stack. The intention is that the agent server will only complete the second (synchronous) 
    1.52 +// message after receiving and doing initial processing of the first (asynchronous) message, which may include, for 
    1.53 +// example, reading the uri descriptor. 
    1.54 +// However, an obvious disadvantage of this pattern is that it incurs a second IPC call, and so may degrade performance.<br>
    1.55 +// Moreover, there are several caveats which must hold true in order for the pattern to work:
    1.56 +// 1. The kernel delivers messages in the order that they are sent (this is currently true).<br>
    1.57 +// 2. The agent server is guaranteed to finish processing the first message before completing the second message.<br>
    1.58 +// This requires understanding of the agent server implementation.<br>
    1.59 +// 3. After initial processing of the first (asynchronous) message the agent server does not need to 
    1.60 +// access the memory supplied in the message again. This requires understanding of the agent server implementation.<br>
    1.61 +// 4. The synchronous call is a request that has no effect on the state of the agent server - a 'no operation'
    1.62 +// may or may not be possible.
    1.63 +// <b> 
    1.64 +// 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.
    1.65 +// <b>
    1.66 +// 
    1.67 +//
    1.68 +
    1.69 +/**
    1.70 + @page CAFAsyncSendReceive Making an asynchronous SendReceive() call in an agent plugin
    1.71 + - @ref StoreLocalCopy
    1.72 + - @ref SyncSendReceive
    1.73 + @section StoreLocalCopy Storing a local heap copy of transient data
    1.74 + @code
    1.75 + @endcode
    1.76 + @section SyncSendReceive Following the asynchronous call with a synchronous call
    1.77 + @code
    1.78 + @endcode
    1.79 +*/