Adaptation/GUID-12EFB295-C527-5F96-81F1-6021D335D865.dita
changeset 15 307f4279f433
equal deleted inserted replaced
14:578be2adaf3e 15:307f4279f433
       
     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-12EFB295-C527-5F96-81F1-6021D335D865" xml:lang="en"><title>Thread
       
    13 Termination</title><shortdesc>This topic describes how and in what conditions to kill a kernel
       
    14 side thread. </shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    15 <p>The only way to kill a kernel side thread is for code running in that thread
       
    16 to call <xref href="GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D.dita#GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D/GUID-808B3622-BDC4-376D-96E9-16281BA28AF8"><apiname>Kern::Exit()</apiname></xref>. </p>
       
    17 <p>A kernel side thread can kill itself, but cannot kill any other kernel
       
    18 side thread. This avoids the overhead of critical sections. Remember that
       
    19 a kernel side thread <i>can</i> kill a user side thread. </p>
       
    20 <p>In practice, device drivers will create threads that can run queued DFCs
       
    21 (Deferred Function Calls) only if they choose not to use the two supplied
       
    22 DFC threads, known as DFC thread 0 and DFC thread 1. </p>
       
    23 <section id="GUID-A5B308C7-21CE-437E-A033-A373E1E2FE78"><title>How to kill a thread running queued DFCs</title> <p>In principle
       
    24 the only way to kill a thread that runs queued DFCs is to schedule a DFC that
       
    25 simply calls <xref href="GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D.dita#GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D/GUID-808B3622-BDC4-376D-96E9-16281BA28AF8"><apiname>Kern::Exit()</apiname></xref>. The DFC should have priority
       
    26 0 (the lowest). We refer to this as a 'kill' DFC. </p> <p>In practice you
       
    27 create a 'kill' DFC by creating a <xref href="GUID-A14562A5-3E91-3113-AB3C-71DBEA9D58EB.dita"><apiname>TDfc</apiname></xref> object, and then
       
    28 make the DFC's callback function include a call to <xref href="GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D.dita#GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D/GUID-808B3622-BDC4-376D-96E9-16281BA28AF8"><apiname>Kern::Exit()</apiname></xref>.
       
    29 You then queue the DFC onto the DFC queue, a <xref href="GUID-24B2FEDB-9273-351F-A1C6-6F5F91BF83B7.dita"><apiname>TDfcQue</apiname></xref> object,
       
    30 from the destructor of the logical device driver's factory class, i.e. the
       
    31 destructor of the class derived from <xref href="GUID-7616AA05-83E6-3989-AB9D-11AE01245BEB.dita"><apiname>DLogicalDevice</apiname></xref>. </p> </section>
       
    32 <section id="GUID-3DB34648-94EC-4AF4-9550-EF7753FC18BE"><title>Issues to be aware of</title> <ol id="GUID-6335774D-CEDB-52AE-BBED-AFA7CB55DFF5">
       
    33 <li id="GUID-0573932A-B43C-50B0-9458-B213A6C4346F"><p>You need to make sure
       
    34 that no other DFCs are on that DFC queue at the time that the 'kill' DFC runs
       
    35 as there is no automatic cleanup. </p> <p>Perform cleanup by calling <codeph>Cancel()</codeph> (i.e. <xref href="GUID-A14562A5-3E91-3113-AB3C-71DBEA9D58EB.dita#GUID-A14562A5-3E91-3113-AB3C-71DBEA9D58EB/GUID-9851B90B-8D05-3C86-B083-44C4564AC140"><apiname>TDfc::Cancel()</apiname></xref>)
       
    36 on all queued DFCs. </p> </li>
       
    37 <li id="GUID-F9D0239F-9174-54B5-B39B-5D1E54FF6EF5"><p>You need to make sure
       
    38 that the DFC queue object, i.e. the <xref href="GUID-24B2FEDB-9273-351F-A1C6-6F5F91BF83B7.dita"><apiname>TDfcQue</apiname></xref> object, and
       
    39 the 'kill' DFC object, i.e. the <xref href="GUID-A14562A5-3E91-3113-AB3C-71DBEA9D58EB.dita"><apiname>TDfc</apiname></xref> object, are not destroyed
       
    40 before the 'kill' DFC has a chance to run. </p> <p>You can do this by making
       
    41 both the DFC queue object and the 'kill' DFC object static objects within
       
    42 the driver. The device driver will only be unloaded from RAM by the null thread.
       
    43 By queuing the 'kill' DFC on the DFC thread, you mark it ready-to-run, which
       
    44 means that your 'kill' DFC will run before the driver is unloaded and before
       
    45 the DFC queue object and the 'kill' DFC object vanish. </p> </li>
       
    46 <li id="GUID-29195090-756E-5FB7-BF78-0F6C6C5A7983"><p>You need to make sure
       
    47 that any code queued to run on your DFC thread never hangs. </p> <p>The important
       
    48 point is that <xref href="GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D.dita#GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D/GUID-808B3622-BDC4-376D-96E9-16281BA28AF8"><apiname>Kern::Exit()</apiname></xref> can only be used by the thread
       
    49 itself, but if the thread hangs, then it can execute nothing. This means that
       
    50 kernel side threads must be written very carefully so they cannot hang. Any
       
    51 defect in kernel side code is likely to be fatal. </p> <p>It may be that you
       
    52 have to consider writing defensive style code; for example, if your thread
       
    53 is waiting for an event, you could consider using a timer to wake it up in
       
    54 case the expected event never happens. Alternatively, you could consider moving
       
    55 some processing to the user side. </p> </li>
       
    56 </ol> </section>
       
    57 </conbody></concept>