1 | /* |
2 | * $Id: NativeLeakDetectionThread.java,v 1.3 2005/06/28 06:42:53 hastings Exp $ |
3 | * |
4 | * (c) Copyright, Moebius Solutions, Inc., 2004 |
5 | * |
6 | * All Rights Reserved |
7 | * |
8 | * This material may be reproduced by or for the U. S. Government |
9 | * pursuant to the copyright license under the clause at |
10 | * DFARS 252.227-7014 (OCT 2001). |
11 | */ |
12 | |
13 | package com.moesol.bindings; |
14 | |
15 | import java.lang.ref.Reference; |
16 | import java.lang.ref.ReferenceQueue; |
17 | import java.util.logging.Logger; |
18 | |
19 | /** |
20 | * This singleton thread checks for native resource leaks. |
21 | * Use getQ to get a RefenceQueue suitable for |
22 | * the PhantomReference contructor. Derive a class |
23 | * from PhantomRefernce that implements the NativeResourceChecker |
24 | * interface. |
25 | * When the referent become phantomly reachable |
26 | * NativeResourceChecker.check is called. |
27 | * |
28 | * @author robert |
29 | */ |
30 | public class NativeLeakDetectionThread extends Thread { |
31 | /** @return the leak detection thread. */ |
32 | public static NativeLeakDetectionThread instance() { |
33 | return s_instance; |
34 | } |
35 | private NativeLeakDetectionThread() { |
36 | super("NativeLeakDetectionThread"); |
37 | setDaemon(true); |
38 | } |
39 | private static NativeLeakDetectionThread s_instance; |
40 | static { |
41 | s_instance = new NativeLeakDetectionThread(); |
42 | s_instance.start(); |
43 | } |
44 | |
45 | /** Thread entry point */ |
46 | public void run() { |
47 | while (true) { |
48 | try { |
49 | Reference r = getQ().remove(100); |
50 | if (r == null) { |
51 | continue; |
52 | } |
53 | r.clear(); |
54 | if (!isExpectedReference(r)) { |
55 | logger.severe("Unexpected reference"); |
56 | continue; |
57 | } |
58 | NativeResourceChecker c = (NativeResourceChecker)r; |
59 | c.check(); |
60 | } catch (InterruptedException e) { |
61 | // goodbye |
62 | return; |
63 | } |
64 | } |
65 | } |
66 | |
67 | /** Stop the leak detection thread */ |
68 | public void stopRunning() { |
69 | interrupt(); |
70 | } |
71 | private boolean isExpectedReference(Reference r) { |
72 | return r instanceof NativeResourceChecker; |
73 | } |
74 | |
75 | /** @return get the reference Q **/ |
76 | public ReferenceQueue getQ() { |
77 | return m_refq; |
78 | } |
79 | |
80 | private ReferenceQueue m_refq = new ReferenceQueue(); |
81 | private static Logger logger |
82 | = Logger.getLogger(NativeLeakDetectionThread.class.getName()); |
83 | } |