|
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> |