[archstudio-commits] svn commit: r7068 - /utils/trunk/edu.uci.isr.sysutils/src/edu/uci/isr/sysutils/ThreadEventsLock.java

archstudio-commits-owner at uci.edu archstudio-commits-owner at uci.edu
Fri May 2 12:14:47 PDT 2008


Author: shendric
Date: Fri May  2 12:14:47 2008
New Revision: 7068

Log:
Fixed deadlock issues

Modified:
    utils/trunk/edu.uci.isr.sysutils/src/edu/uci/isr/sysutils/ThreadEventsL=
ock.java

Modified: utils/trunk/edu.uci.isr.sysutils/src/edu/uci/isr/sysutils/ThreadE=
ventsLock.java
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- utils/trunk/edu.uci.isr.sysutils/src/edu/uci/isr/sysutils/ThreadEventsL=
ock.java (original)
+++ utils/trunk/edu.uci.isr.sysutils/src/edu/uci/isr/sysutils/ThreadEventsL=
ock.java Fri May  2 12:14:47 2008
@@ -2,30 +2,27 @@
 =

 import java.io.NotSerializableException;
 import java.io.ObjectStreamException;
-import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Queue;
 import java.util.concurrent.locks.ReentrantLock;
 =

 public class ThreadEventsLock<T>
 	extends ReentrantLock{
 =

-	static class ThreadEvents<T>{
+	static class ThreadEvent<T>{
 =

 		Thread thread;
-		List<T> events;
+		T event;
 =

-		public ThreadEvents(Thread thread, List<T> events){
+		public ThreadEvent(Thread thread, T event){
 			this.thread =3D thread;
-			this.events =3D events;
+			this.event =3D event;
 		}
 =

 		@Override
 		public String toString(){
-			return thread.toString() + "(" + events.size() + ")";
+			return thread.toString();
 		}
 	}
 =

@@ -47,66 +44,63 @@
 		eventListeners.remove(listener);
 	}
 =

-	private final Collection<Thread> threadsWithEvents =3D Collections.synchr=
onizedCollection(new HashBag<Thread>());
-	private final Queue<ThreadEvents<T>> pendingThreadEvents =3D new LinkedLi=
st<ThreadEvents<T>>();
-	private volatile List<T> pendingEvents =3D new ArrayList<T>();
+	private final List<ThreadEvent<T>> pendingThreadEvents =3D Collections.sy=
nchronizedList(new LinkedList<ThreadEvent<T>>());
 =

 	public void enqueueEvent(T event){
-		synchronized(this){
-			assert isHeldByCurrentThread();
-			pendingEvents.add(event);
-		}
+		assert isHeldByCurrentThread();
+		pendingThreadEvents.add(new ThreadEvent<T>(Thread.currentThread(), event=
));
 	}
 =

-	private Thread firingThread =3D null;
+	private volatile Thread processingEventThread =3D null;
 =

 	@Override
 	public void unlock(){
-		final Thread currentThread =3D Thread.currentThread();
-		synchronized(this){
-			if(getHoldCount() > 1 || pendingEvents.isEmpty()){
-				super.unlock();
-				return;
-			}
-			threadsWithEvents.add(currentThread);
-			pendingThreadEvents.add(new ThreadEvents<T>(currentThread, pendingEvent=
s));
-			pendingEvents =3D new ArrayList<T>();
-
+		try{
 			super.unlock();
+			final Thread currentThread =3D Thread.currentThread();
 =

-			if(firingThread =3D=3D currentThread){
-				return;
-			}
-		}
-		while(threadsWithEvents.remove(currentThread)){
-			ThreadEvents<T> threadEvents;
-			synchronized(this){
-				while((threadEvents =3D pendingThreadEvents.peek()).thread !=3D curren=
tThread){
-					try{
-						this.wait();
+			while(processingEventThread !=3D currentThread && !pendingThreadEvents.=
isEmpty()){
+				ThreadEvent<T> te =3D null;
+				synchronized(pendingThreadEvents){
+					if(pendingThreadEvents.isEmpty()){
+						break;
+					}
+					if(pendingThreadEvents.get(0).thread !=3D currentThread){
+						try{
+							pendingThreadEvents.wait(0);
+						}
+						catch(InterruptedException e){
+							e.printStackTrace();
+						}
 					}
-					catch(InterruptedException e){
-						e.printStackTrace();
+					else{
+						te =3D pendingThreadEvents.remove(0);
 					}
 				}
-				firingThread =3D currentThread;
-			}
-			assert threadEvents.thread =3D=3D currentThread;
-			try{
-				for(T evt: threadEvents.events){
-					for(IEventListener<T> l: eventListeners.getListeners()){
-						l.handleEvent(evt);
+				if(te !=3D null){
+					assert te.thread =3D=3D currentThread;
+					try{
+						processingEventThread =3D currentThread;
+						for(IEventListener<T> l: eventListeners.getListeners()){
+							try{
+								l.handleEvent(te.event);
+							}
+							catch(Throwable t){
+								t.printStackTrace();
+							}
+						}
+					}
+					finally{
+						processingEventThread =3D null;
+						synchronized(pendingThreadEvents){
+							pendingThreadEvents.notifyAll();
+						}
 					}
 				}
 			}
-			catch(Throwable t){
-				t.printStackTrace();
-			}
-			synchronized(this){
-				pendingThreadEvents.remove();
-				firingThread =3D null;
-				this.notifyAll();
-			}
+		}
+		catch(Throwable t){
+			t.printStackTrace();
 		}
 	}
 }
\ No newline at end of file




More information about the archstudio-commits mailing list