Symbian3/PDK/Source/GUID-B7B7F611-BCA0-498F-BEC1-16B276F680D5.dita
changeset 3 46218c8b8afa
parent 1 25a17d01db0c
child 5 f345bda72bc4
--- a/Symbian3/PDK/Source/GUID-B7B7F611-BCA0-498F-BEC1-16B276F680D5.dita	Thu Mar 11 15:24:26 2010 +0000
+++ b/Symbian3/PDK/Source/GUID-B7B7F611-BCA0-498F-BEC1-16B276F680D5.dita	Thu Mar 11 18:02:22 2010 +0000
@@ -1,200 +1,200 @@
-<?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-B7B7F611-BCA0-498F-BEC1-16B276F680D5" xml:lang="en"><title>Calling
-Symbian Asynchronous APIs in Applications</title><shortdesc/><prolog><metadata><keywords/></metadata></prolog><conbody>
-<p>When porting an P.I.P.S.-based C or C++ application on top of Symbian C++,
-the developer may need to make use of Symbian asynchronous APIs. If asynchronous
-APIs are made use of in an P.I.P.S. application, the application needs to
-wait for the completion of the asynchronous API. This can be done in two ways:
- <ul>
-<li><p>Wait for the asynchronous request to complete. This can be achieved
-by making use of <codeph>User::WaitForRequest(iStatus)</codeph>; where <codeph>iStatus</codeph> is
-the <codeph>TRequestSemaphore</codeph> used by the asynchronous API. </p></li>
-<li><p>Call the asynchronous API in an active object, run an active scheduler,
-and let the active scheduler wait for the asynchronous operation to complete. </p></li>
-</ul></p>
-<p><b>The problems with these approaches are: </b></p>
-<p>The open source application would get blocked till the asynchronous operation
-completes in the first approach. In the second approach, the active scheduler
-would be running in a wait loop, checking for asynchronous API completion.
-Even in this case, the P.I.P.S. application would not be able to perform any
-other operations outside the active scheduler framework.</p>
-<p>The asynchronous APIs could be called in a separate process, and the P.I.P.S.
-application could communicate with this process by making use of the client/server
-framework of Symbian or by making use of other P.I.P.S. IPC mechanisms. However,
-making a different process for calling asynchronous APIs might pose a performance
-hit.</p>
-<p>One of the ways to solve these problems is to call the asynchronous APIs
-in a separate thread.</p>
-<p><b>Example:</b></p>
-<codeblock xml:space="preserve">class CActiveThread:  public CActive
-{
-public: 
-
-    enum TState
-    {
-    EInitialized = 0x0,
-    EDoFirst = 0x1,
-    EDoSecond = 0x2,
-    EDoThird = 0x4,
-    ECompleted = 0x8
-    };
- 
-     // thread startup routine
-    static int StartMyThread(void* thisptr);
-    // leaving variant of the thread startup routine
-    static int StartMyThreadL(void* thisptr);
-    // Helper function to start the thread
-    void StartThread();    
-    // Do Function
-    void DoFunction(TState aState );      
-              
-    // CActive Functions
-    void RunL();
-    void DoCancel();
-    		
-    // Constructors and destructor      
-    static CActiveThread* NewL(); 
-    CActiveThread ();
-    void ConstructL();
-    ~ CActiveThread();      
-           
-private:    
-  
-    // Active Scheduler
-    CActiveSchedulerWait *iWait;          
-    // Command/State
-    TInt iState;        	    
-    TRequestStatus iThreadExitWait;	    
-    // my thread handle
-    RThread iActiveThread;    	    
-    sem_t iSem;
-};
-</codeblock>
-<p>The <codeph>StartThread</codeph> member function of <xref href="GUID-7968C6B4-3247-335A-845B-3D196E2EB14C.dita"><apiname>CActiveThread</apiname></xref> creates
-the thread which runs the active scheduler. <codeph>StartMyThread</codeph> is
-the entry point function for the new thread that starts an active scheduler
-and sets up the clean up stack. To call an asynchronous function, <codeph>DoFunction()</codeph> needs
-to be called with the corresponding state. The parent thread signals the child
-thread using the child thread’s thread request semaphore. When the thread
-request semaphore is signaled, the child thread wakes up, calls the corresponding
-asynchronous API in <codeph>RunL()</codeph> based on the <codeph>iState</codeph> and
-again goes back to the active scheduler wait loop.  </p>
-<p>To synchronize between the parent thread and the child thread, a semaphore
-can be used as shown in the following code snippet. </p>
-<codeblock xml:space="preserve">CActiveThread* CActiveThread::NewL()
-{
-CActiveThread* self = new (ELeave) CActiveThread();
-self-&gt;ConstructL();
-return self;
-}
-     
-CActiveThread::CActiveThread():CActive(EPriorityStandard),iState(EInitialized)
-{       
-}
-
-void CActiveThread::ConstructL()
-{  
-// semaphore for Synching
-sem_init(&amp;iSem,0,0);  
-}
-     
-void CActiveThread::StartThread()
-{       
-//Create Thread 
-TInt err = iActiveThread.Create( KThreadName(),&amp;CActiveThread::StartMyThread, KDefaultStackSize, NULL, (TAny*)this );
-iActiveThread.Logon( iThreadExitWait );
-iActiveThread.Resume();
-sem_wait(&amp;iSem );    
-}
- 
-int CActiveThread::StartMyThread( void* ptr )
-{
-CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
-CActiveScheduler::Install(scheduler);     
-CTrapCleanup* pCleanup = CTrapCleanup::New();
-TRAPD(err, StartMyThreadL(ptr));        
-}
- 
-int CActiveThread::StartMyThreadL( void* ptr )
-{        
-CActiveThread *thisptr = (CActiveThread*)ptr;    
-CActiveScheduler::Add(thisptr);
-thisptr-&gt;iWait = new (ELeave) CActiveSchedulerWait();	    
-thisptr-&gt;iState = EInitialized;
-thisptr-&gt;iStatus = KRequestPending;
-thisptr-&gt;SetActive();
-sem_post( &amp;(thisptr-&gt;iSem ));    
-thisptr-&gt;iWait-&gt;Start();   
-}
-
- void CActiveThread::RunL()
- {
- switch ( iState )
-     {
-     case  EDoFirst:
-     // Call 1st asynchronous function
-     break;
-     
-     case EDoSecond:
-     // Call 2nd asynchronous function
-     break;
-      
-     case EDoThird:
-     // Call 3rd asynchronous function
-     break;
-     
-     case ECompleted:
-     iWait-&gt;AsyncStop();    
-     return;			
-     }
-	
-iStatus = KRequestPending;
-SetActive();
-// wake up the waiting thread
-sem_post(&amp;iSem);
-}
-
-void CActiveThread::DoCancel()
-{    
-}
-
-void CActiveThread::DoFunction(TState aState )
-{
-iState = aState;
-TRequestStatus *reqPtr = &amp;iStatus;
-iActiveThread.RequestComplete( reqPtr, KErrNone );
-sem_wait(&amp;iSem);
-}    
- 
-CActiveThread::~CActiveThread()
-{  
-if ( iState != EInitialized )
-    {
-    iState = ECompleted;
-    TRequestStatus *reqPtr = &amp;iStatus;	
-    iActiveThread.RequestComplete( reqPtr, KErrNone ); 
-    User::WaitForRequest( iThreadExitWait);
-    }    
-sem_destroy(&amp;iSem);
-}
-</codeblock>
-<p><b>Using <xref href="GUID-7968C6B4-3247-335A-845B-3D196E2EB14C.dita"><apiname>CActiveThread</apiname></xref>:</b></p>
-<codeblock xml:space="preserve">iMyAsyncIf = CActiveThread::NewL();   
-iMyAsyncIf-&gt;StartThread();    
-iMyAsyncIf-&gt;DoFunction(EDoFirst);
-</codeblock>
-<p><b>Limitations: </b></p>
-<p>In this approach, only the parent thread communicates with the child thread.
-There is no way for the child thread to communicate with the parent thread.
- </p>
+<?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-B7B7F611-BCA0-498F-BEC1-16B276F680D5" xml:lang="en"><title>Calling
+Symbian Asynchronous APIs in Applications</title><shortdesc/><prolog><metadata><keywords/></metadata></prolog><conbody>
+<p>When porting an P.I.P.S.-based C or C++ application on top of Symbian C++,
+the developer may need to make use of Symbian asynchronous APIs. If asynchronous
+APIs are made use of in an P.I.P.S. application, the application needs to
+wait for the completion of the asynchronous API. This can be done in two ways:
+ <ul>
+<li><p>Wait for the asynchronous request to complete. This can be achieved
+by making use of <codeph>User::WaitForRequest(iStatus)</codeph>; where <codeph>iStatus</codeph> is
+the <codeph>TRequestSemaphore</codeph> used by the asynchronous API. </p></li>
+<li><p>Call the asynchronous API in an active object, run an active scheduler,
+and let the active scheduler wait for the asynchronous operation to complete. </p></li>
+</ul></p>
+<p><b>The problems with these approaches are: </b></p>
+<p>The open source application would get blocked till the asynchronous operation
+completes in the first approach. In the second approach, the active scheduler
+would be running in a wait loop, checking for asynchronous API completion.
+Even in this case, the P.I.P.S. application would not be able to perform any
+other operations outside the active scheduler framework.</p>
+<p>The asynchronous APIs could be called in a separate process, and the P.I.P.S.
+application could communicate with this process by making use of the client/server
+framework of Symbian or by making use of other P.I.P.S. IPC mechanisms. However,
+making a different process for calling asynchronous APIs might pose a performance
+hit.</p>
+<p>One of the ways to solve these problems is to call the asynchronous APIs
+in a separate thread.</p>
+<p><b>Example:</b></p>
+<codeblock xml:space="preserve">class CActiveThread:  public CActive
+{
+public: 
+
+    enum TState
+    {
+    EInitialized = 0x0,
+    EDoFirst = 0x1,
+    EDoSecond = 0x2,
+    EDoThird = 0x4,
+    ECompleted = 0x8
+    };
+ 
+     // thread startup routine
+    static int StartMyThread(void* thisptr);
+    // leaving variant of the thread startup routine
+    static int StartMyThreadL(void* thisptr);
+    // Helper function to start the thread
+    void StartThread();    
+    // Do Function
+    void DoFunction(TState aState );      
+              
+    // CActive Functions
+    void RunL();
+    void DoCancel();
+    		
+    // Constructors and destructor      
+    static CActiveThread* NewL(); 
+    CActiveThread ();
+    void ConstructL();
+    ~ CActiveThread();      
+           
+private:    
+  
+    // Active Scheduler
+    CActiveSchedulerWait *iWait;          
+    // Command/State
+    TInt iState;        	    
+    TRequestStatus iThreadExitWait;	    
+    // my thread handle
+    RThread iActiveThread;    	    
+    sem_t iSem;
+};
+</codeblock>
+<p>The <codeph>StartThread</codeph> member function of <xref href="GUID-7968C6B4-3247-335A-845B-3D196E2EB14C.dita"><apiname>CActiveThread</apiname></xref> creates
+the thread which runs the active scheduler. <codeph>StartMyThread</codeph> is
+the entry point function for the new thread that starts an active scheduler
+and sets up the clean up stack. To call an asynchronous function, <codeph>DoFunction()</codeph> needs
+to be called with the corresponding state. The parent thread signals the child
+thread using the child thread’s thread request semaphore. When the thread
+request semaphore is signaled, the child thread wakes up, calls the corresponding
+asynchronous API in <codeph>RunL()</codeph> based on the <codeph>iState</codeph> and
+again goes back to the active scheduler wait loop.  </p>
+<p>To synchronize between the parent thread and the child thread, a semaphore
+can be used as shown in the following code snippet. </p>
+<codeblock xml:space="preserve">CActiveThread* CActiveThread::NewL()
+{
+CActiveThread* self = new (ELeave) CActiveThread();
+self-&gt;ConstructL();
+return self;
+}
+     
+CActiveThread::CActiveThread():CActive(EPriorityStandard),iState(EInitialized)
+{       
+}
+
+void CActiveThread::ConstructL()
+{  
+// semaphore for Synching
+sem_init(&amp;iSem,0,0);  
+}
+     
+void CActiveThread::StartThread()
+{       
+//Create Thread 
+TInt err = iActiveThread.Create( KThreadName(),&amp;CActiveThread::StartMyThread, KDefaultStackSize, NULL, (TAny*)this );
+iActiveThread.Logon( iThreadExitWait );
+iActiveThread.Resume();
+sem_wait(&amp;iSem );    
+}
+ 
+int CActiveThread::StartMyThread( void* ptr )
+{
+CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
+CActiveScheduler::Install(scheduler);     
+CTrapCleanup* pCleanup = CTrapCleanup::New();
+TRAPD(err, StartMyThreadL(ptr));        
+}
+ 
+int CActiveThread::StartMyThreadL( void* ptr )
+{        
+CActiveThread *thisptr = (CActiveThread*)ptr;    
+CActiveScheduler::Add(thisptr);
+thisptr-&gt;iWait = new (ELeave) CActiveSchedulerWait();	    
+thisptr-&gt;iState = EInitialized;
+thisptr-&gt;iStatus = KRequestPending;
+thisptr-&gt;SetActive();
+sem_post( &amp;(thisptr-&gt;iSem ));    
+thisptr-&gt;iWait-&gt;Start();   
+}
+
+ void CActiveThread::RunL()
+ {
+ switch ( iState )
+     {
+     case  EDoFirst:
+     // Call 1st asynchronous function
+     break;
+     
+     case EDoSecond:
+     // Call 2nd asynchronous function
+     break;
+      
+     case EDoThird:
+     // Call 3rd asynchronous function
+     break;
+     
+     case ECompleted:
+     iWait-&gt;AsyncStop();    
+     return;			
+     }
+	
+iStatus = KRequestPending;
+SetActive();
+// wake up the waiting thread
+sem_post(&amp;iSem);
+}
+
+void CActiveThread::DoCancel()
+{    
+}
+
+void CActiveThread::DoFunction(TState aState )
+{
+iState = aState;
+TRequestStatus *reqPtr = &amp;iStatus;
+iActiveThread.RequestComplete( reqPtr, KErrNone );
+sem_wait(&amp;iSem);
+}    
+ 
+CActiveThread::~CActiveThread()
+{  
+if ( iState != EInitialized )
+    {
+    iState = ECompleted;
+    TRequestStatus *reqPtr = &amp;iStatus;	
+    iActiveThread.RequestComplete( reqPtr, KErrNone ); 
+    User::WaitForRequest( iThreadExitWait);
+    }    
+sem_destroy(&amp;iSem);
+}
+</codeblock>
+<p><b>Using <xref href="GUID-7968C6B4-3247-335A-845B-3D196E2EB14C.dita"><apiname>CActiveThread</apiname></xref>:</b></p>
+<codeblock xml:space="preserve">iMyAsyncIf = CActiveThread::NewL();   
+iMyAsyncIf-&gt;StartThread();    
+iMyAsyncIf-&gt;DoFunction(EDoFirst);
+</codeblock>
+<p><b>Limitations: </b></p>
+<p>In this approach, only the parent thread communicates with the child thread.
+There is no way for the child thread to communicate with the parent thread.
+ </p>
 </conbody></concept>
\ No newline at end of file