1 package com4j; 2 3 import java.util.List ; 4 import java.util.ArrayList ; 5 6 7 16 final class ComThread extends Thread { 17 18 21 private static final ThreadLocal <ComThread> map = new ThreadLocal <ComThread>() { 22 public ComThread initialValue() { 23 if( isComThread() ) 24 return (ComThread)Thread.currentThread(); 25 else 26 return new ComThread(Thread.currentThread()); 27 } 28 }; 29 30 33 static ComThread get() { 34 return map.get(); 35 } 36 37 38 39 private ComThread(Thread peer) { 40 super("ComThread for "+peer.getName()); 41 this.peer = peer; 42 setDaemon(true); start(); 44 } 45 46 49 private final Thread peer; 50 51 55 private Wrapper freeList; 56 57 60 private Task<?> taskList; 61 62 65 private int liveObjects = 0; 66 67 70 private final List <ComObjectListener> listeners = new ArrayList <ComObjectListener>(); 71 72 75 private boolean canExit() { 76 return !peer.isAlive() && liveObjects==0; 77 } 78 79 public synchronized void run() { 80 Native.coInitialize(); 81 82 while(!canExit()) { 84 try { 85 wait(1000); 86 } catch (InterruptedException e) {} 87 88 while(freeList!=null) { 90 if(freeList.dispose0()) 91 liveObjects--; 92 freeList = freeList.next; 93 } 94 95 while(taskList!=null) { 97 Task<?> task = taskList; 98 taskList = task.next; 99 task.invoke(); 100 } 101 } 102 103 Native.coUninitialize(); 104 } 105 106 109 synchronized void addToFreeList(Wrapper wrapper) { 110 assert wrapper.next==null; 111 wrapper.next = freeList; 112 freeList = wrapper; 113 } 114 115 119 public <T> T execute(Task<T> task) { 120 synchronized(task) { 121 synchronized(this) { 122 task.next = taskList; 124 taskList = task; 125 126 notify(); 128 } 129 try { 131 task.wait(); 132 } catch (InterruptedException e) {} 133 134 if(task.exception!=null) { 135 RuntimeException e = task.exception; 136 task.exception = null; 137 e.fillInStackTrace(); 138 throw e; 139 } else { 140 T r = task.result; 141 task.result = null; 142 return r; 143 } 144 } 145 } 146 147 public synchronized void addLiveObject( Com4jObject r ) { 148 liveObjects++; 149 if(!listeners.isEmpty()) { 150 for( int i=listeners.size()-1; i>=0; i-- ) 151 listeners.get(i).onNewObject(r); 152 } 153 } 154 155 158 static boolean isComThread() { 159 return Thread.currentThread() instanceof ComThread; 160 } 161 162 public void addListener(ComObjectListener listener) { 163 if(listener==null) 164 throw new IllegalArgumentException ("listener is null"); 165 if(listeners.contains(listener)) 166 throw new IllegalArgumentException ("can't register the same listener twice"); 167 listeners.add(listener); 168 } 169 170 public void removeListener(ComObjectListener listener) { 171 if(!listeners.remove(listener)) 172 throw new IllegalArgumentException ("listener isn't registered"); 173 } 174 } 175 | Popular Tags |