Symbian3/SDK/Source/GUID-A4799558-AF8C-5E97-9B03-7D1C04FEC243.dita
changeset 7 51a74ef9ed63
child 8 ae94777fff8f
equal deleted inserted replaced
6:43e37759235e 7:51a74ef9ed63
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept id="GUID-A4799558-AF8C-5E97-9B03-7D1C04FEC243" xml:lang="en"><title>Duplicating
       
    13 handles to Kernel side objects</title><shortdesc>This document describes when you should duplicate a handle in kernel
       
    14 side programming.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    15 <section id="GUID-E9B67C16-E1D1-42D4-872D-6731F94DBC87"><title>Duplicating a thread-relative handle in another thread</title> <p>A
       
    16 handle in one thread (a thread-relative handle) may be duplicated in another
       
    17 thread within the same process.</p> <p>Typically, thread B may want to access
       
    18 a Kernel object which already exists and for which thread A, within the same
       
    19 process, already holds a handle.</p> <p>For example, if thread A has a handle
       
    20 on a semaphore, it is insufficient to pass a copy of the handle, an <codeph>RSemaphore</codeph>,
       
    21 to thread B. The handle passed to thread B does not refer to anything known
       
    22 by thread B. In order for thread B to gain a valid handle on the DLL, the
       
    23 handle must be duplicated.</p> <p>Note that, in practice, real code may or
       
    24 may not want to duplicate a semaphore handle, however the principle remains
       
    25 valid.</p> <p>In thread B, then:</p> <codeblock id="GUID-A6110799-7A92-5EF9-9AE8-CBB532D7542B" xml:space="preserve">...
       
    26 RSemaphore cs;
       
    27 cs.SetHandle(h.Handle()); 
       
    28                           // ...where  h  is an RSemaphore, the
       
    29                           // handle to the DLL, and
       
    30                           // passed from thread A code.
       
    31                                   
       
    32 cs.Duplicate(tA);
       
    33                           // ...where  tA  is an RThread, the handle to
       
    34                           // thread A, and passed from threadA code.
       
    35                           // Duplicate also opens the resulting
       
    36                           // handle, cs.
       
    37 ...
       
    38 </codeblock> <p>The dotted line in the following diagram shows the effect
       
    39 of this:</p> <fig id="GUID-731954F6-D85E-5940-96A4-15AC6E3AA5F5">
       
    40 <image href="GUID-5BABDDEC-1D81-5847-9ADB-65DF8E404BFA_d0e234496_href.png" placement="inline"/>
       
    41 </fig> <p>Note that for process-relative handles, there is no need to use <codeph>Duplicate()</codeph>;
       
    42 the handle passed from thread A to thread B can be used directly.</p> </section>
       
    43 <section id="GUID-83BE173E-F73D-46A8-8267-A1055E486FE3"><title>Making specific handles from generic handles</title> <p>There
       
    44 are two types of generic handle, one for threads and one for processes, both
       
    45 of which are created using the default constructor of the appropriate handle.</p> <codeblock id="GUID-F42A0EEB-3142-527A-9BD4-724B9969CF5D" xml:space="preserve">RThread  thisThread;  // Generic handle meaning "the current thread"
       
    46 RProcess thisProcess; // Generic handle meaning "the current process"
       
    47 </codeblock> <p>An important fact about generic handles is that they make
       
    48 no claim on the object that they refer to, so you don't need to call <codeph>Close()</codeph> when
       
    49 you get rid of them. This is not true of specific handles, which always add
       
    50 a reference to the object that they refer to, preventing that object being
       
    51 fully destroyed until all specific handles have been closed.</p> <p>Use Duplicate()
       
    52 to make a specific handle from a generic handle; for example:</p> <codeblock id="GUID-D5588FB1-8ACE-526F-A8D7-6E2C5C089823" xml:space="preserve">RThread thisThread;                        // generic handle
       
    53 TInt err=thisThread.Duplicate(thisThread);    // a specific handle
       
    54 ...
       
    55 thisThread.Close();                        // don't forget.
       
    56 </codeblock> </section>
       
    57 <section id="GUID-83C281F6-1C91-4F1A-9C69-3C5BF3843DE5"><title>Promoting a thread-relative handle to a process-wide handle</title> <p>The
       
    58 second parameter passed to <codeph>Duplicate()</codeph> specifies whether
       
    59 the resulting handle is specific to the calling thread, or is valid for all
       
    60 threads in the same process.</p> <p><codeph>Duplicate()</codeph> offers a
       
    61 way of making a handle, which is specific to a thread, known to all the threads
       
    62 in a process.</p> <p>This does not work for all handles but <codeph>RLibrary</codeph> is
       
    63 an example of one where it can make sense to promote an <codeph>RLibrary</codeph> thread-relative
       
    64 handle to a process-relative handle because this ensures that the library
       
    65 will not be automatically unloaded when the original thread terminates. For
       
    66 example:</p> <codeblock id="GUID-E02BE012-EE3F-53A0-A3E0-7B57E03B9D28" xml:space="preserve">...
       
    67 _LIT(KMyLib,"MYLIB");
       
    68 ...
       
    69 RLibrary threadLibrary;
       
    70 err=threadLibrary.Load(KMyLib);        // Load up a DLL, this gives
       
    71                                        // a thread-specific handle.
       
    72 RLibrary aDup=threadLibrary;           // Copies handle without
       
    73                                        // doing Open().
       
    74 err=threadLibrary.Duplicate(RThread());// Overwrite the original.
       
    75 if (err==KErrNone)
       
    76     {
       
    77        aDup.Close();                      // Close the original.
       
    78     }
       
    79 ...
       
    80 </codeblock> </section>
       
    81 </conbody></concept>