summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorStarla Insigna <hatkirby@fourisland.com>2009-02-03 17:31:19 -0500
committerStarla Insigna <hatkirby@fourisland.com>2009-02-03 17:31:19 -0500
commitc791c138d4d73b495c8a355ae01bca754e1ce66b (patch)
treeb82e8f2620e00c5a881dc8be0ae5cac6c9d99096 /src
parent0a37b19bc1afc4369c7e423bb07f432196273bc9 (diff)
downloadfourpuzzle-c791c138d4d73b495c8a355ae01bca754e1ce66b.tar.gz
fourpuzzle-c791c138d4d73b495c8a355ae01bca754e1ce66b.tar.bz2
fourpuzzle-c791c138d4d73b495c8a355ae01bca754e1ce66b.zip
Fixed MoveEventThread latch breakage
Previously, MoveEventThread used a CountDownLatch to power it's moveAll() function. However, because CountDownLatch can only count down and not back up, every time a MoveEventThread was spawned, it's static moveEventWait (which was a CountDownLatch) would be re-instantated. If a thread was already waiting on the CountDownLatch, it would be disrupted.

This meant that if the first MoveEventThread spawned completed before the rest, the entire program would grind to a halt.

This has been fixed by replacing the CountDownLatch with a Semaphore (not exactly what Semaphore is supposed to be used for, but it works). Every time a MoveEventThread is spawned, it acquires a permit from the Semaphone and releases it when it completes. moveAll() then attempts to acquire 100 permits (the Semaphore is initalized to only allow 100 permits), which blocks until all MoveEventThreads have completed. The downside of this is that only 100 MoveEventThreads can execute at once, but it is exceptionally unlikely that such an event will occur. Also, if this does occur, the other MoveEventThreads will simply wait for another to complete and then acquire a permit.
Diffstat (limited to 'src')
-rw-r--r--src/com/fourisland/fourpuzzle/gamestate/mapview/event/specialmove/MoveEventThread.java32
1 files changed, 16 insertions, 16 deletions
diff --git a/src/com/fourisland/fourpuzzle/gamestate/mapview/event/specialmove/MoveEventThread.java b/src/com/fourisland/fourpuzzle/gamestate/mapview/event/specialmove/MoveEventThread.java index df4f4ee..2395dd0 100644 --- a/src/com/fourisland/fourpuzzle/gamestate/mapview/event/specialmove/MoveEventThread.java +++ b/src/com/fourisland/fourpuzzle/gamestate/mapview/event/specialmove/MoveEventThread.java
@@ -10,7 +10,7 @@ import com.fourisland.fourpuzzle.gamestate.mapview.event.Event;
10import com.fourisland.fourpuzzle.gamestate.mapview.event.LayerEvent; 10import com.fourisland.fourpuzzle.gamestate.mapview.event.LayerEvent;
11import java.util.List; 11import java.util.List;
12import java.util.Vector; 12import java.util.Vector;
13import java.util.concurrent.CountDownLatch; 13import java.util.concurrent.Semaphore;
14import java.util.logging.Level; 14import java.util.logging.Level;
15import java.util.logging.Logger; 15import java.util.logging.Logger;
16 16
@@ -19,14 +19,12 @@ import java.util.logging.Logger;
19 * @author hatkirby 19 * @author hatkirby
20 */ 20 */
21public class MoveEventThread implements Runnable { 21public class MoveEventThread implements Runnable {
22
23 private static volatile List<Event> events = new Vector<Event>();
24 private static volatile Semaphore moveEventWait = new Semaphore(100);
22 25
23 public static volatile int countMoveEventThreads = 0; 26 private Event ev;
24 27 private MoveEvent[] actions;
25 static volatile List<Event> events = new Vector<Event>();
26 static volatile CountDownLatch moveEventWait = new CountDownLatch(0);
27
28 Event ev;
29 MoveEvent[] actions;
30 28
31 public MoveEventThread(Event ev, MoveEvent[] actions) 29 public MoveEventThread(Event ev, MoveEvent[] actions)
32 { 30 {
@@ -36,6 +34,12 @@ public class MoveEventThread implements Runnable {
36 34
37 public void run() 35 public void run()
38 { 36 {
37 try {
38 moveEventWait.acquire();
39 } catch (InterruptedException ex) {
40 Logger.getLogger(MoveEventThread.class.getName()).log(Level.SEVERE, null, ex);
41 }
42
39 while (ev.isMoving()) 43 while (ev.isMoving())
40 { 44 {
41 try { 45 try {
@@ -47,18 +51,13 @@ public class MoveEventThread implements Runnable {
47 51
48 events.add(ev); 52 events.add(ev);
49 53
50 MoveEventThread.countMoveEventThreads++;
51 moveEventWait = new CountDownLatch(countMoveEventThreads);
52
53 for (MoveEvent action : actions) 54 for (MoveEvent action : actions)
54 { 55 {
55 action.doAction(ev); 56 action.doAction(ev);
56 } 57 }
57 58
58 events.remove(ev); 59 events.remove(ev);
59 60 moveEventWait.release();
60 MoveEventThread.countMoveEventThreads--;
61 moveEventWait.countDown();
62 } 61 }
63 62
64 /* TODO Rename the two following methods (isHeroMoving and isOtherMoving) 63 /* TODO Rename the two following methods (isHeroMoving and isOtherMoving)
@@ -78,7 +77,8 @@ public class MoveEventThread implements Runnable {
78 public static void moveAll() 77 public static void moveAll()
79 { 78 {
80 try { 79 try {
81 moveEventWait.await(); 80 moveEventWait.acquire(100);
81 moveEventWait.release(100);
82 } catch (InterruptedException ex) { 82 } catch (InterruptedException ex) {
83 Logger.getLogger(MoveEventThread.class.getName()).log(Level.SEVERE, null, ex); 83 Logger.getLogger(MoveEventThread.class.getName()).log(Level.SEVERE, null, ex);
84 } 84 }