deweese 01/10/04 07:48:40 Modified: sources/org/apache/batik/util DoublyLinkedList.java RunnableQueue.java test-sources/org/apache/batik/util RunnableQueueTest.java Log: 1) Added preemptAndWait and peemptLater methods to RunnableQueue These are analogous to invoke* methods but put the runnable at the head of the queue rather than the end of the queue. 2) Added unpop (push to head) and unpush (pop from tail) methods to DoublyLinkedList class (FYI: names come from Perl). 3) Updated RunnableQueueTest to ensure that things aren't broke. Revision Changes Path 1.2 +24 -1 xml-batik/sources/org/apache/batik/util/DoublyLinkedList.java Index: DoublyLinkedList.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/util/DoublyLinkedList.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- DoublyLinkedList.java 2001/08/06 15:35:13 1.1 +++ DoublyLinkedList.java 2001/10/04 14:48:40 1.2 @@ -146,16 +146,39 @@ if (head == null) return null; Node nde = head; - remove(head); + remove(nde); return nde; } /** + * Removes 'tail' from list and returns it. Returns null if list is empty. + * @returns current tail element. + */ + public Node unpush() { + if (head == null) return null; + + Node nde = getTail(); + remove(nde); + return nde; + } + + + + /** * Adds <tt>nde</tt> to tail of list */ public void push(Node nde) { nde.insertBefore(head); if (head == null) head = nde; + size++; + } + + /** + * Adds <tt>nde</tt> to head of list + */ + public void unpop(Node nde) { + nde.insertBefore(head); + head = nde; size++; } } 1.5 +52 -3 xml-batik/sources/org/apache/batik/util/RunnableQueue.java Index: RunnableQueue.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/util/RunnableQueue.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- RunnableQueue.java 2001/08/06 19:38:55 1.4 +++ RunnableQueue.java 2001/10/04 14:48:40 1.5 @@ -16,7 +16,7 @@ * invocation in a single thread. * * @author <a href="mailto:[EMAIL PROTECTED]">Stephane Hillion</a> - * @version $Id: RunnableQueue.java,v 1.4 2001/08/06 19:38:55 deweese Exp $ + * @version $Id: RunnableQueue.java,v 1.5 2001/10/04 14:48:40 deweese Exp $ */ public class RunnableQueue implements Runnable { @@ -168,7 +168,8 @@ } /** - * Schedules the given Runnable object for a later invocation. + * Schedules the given Runnable object for a later invocation, and + * returns. * An exception is thrown if the RunnableQueue was not started. * @throws IllegalStateException if getThread() is null. */ @@ -184,7 +185,7 @@ } /** - * Waits until the given Runnable <tt>run()</tt> has returned. + * Waits until the given Runnable's <tt>run()</tt> has returned. * <em>Note: <tt>invokeAndWait()</tt> must not be called from the * current thread (for example from the <tt>run()</tt> method of the * argument). @@ -204,6 +205,54 @@ LockableLink l = new LockableLink(r); synchronized (list) { list.push(l); + list.notify(); + } + l.lock(); + } + + + /** + * Schedules the given Runnable object for a later invocation, and + * returns. The given runnable preempts any runnable that is not + * currently executing (ie the next runnable started will be the + * one given). An exception is thrown if the RunnableQueue was + * not started. + * @throws IllegalStateException if getThread() is null. + */ + public void preemptLater(Runnable r) { + if (runnableQueueThread == null) { + throw new IllegalStateException + ("RunnableQueue not started or has exited"); + } + synchronized (list) { + list.unpop(new Link(r)); + list.notify(); + } + } + + /** + * Waits until the given Runnable's <tt>run()</tt> has returned. + * The given runnable preempts any runnable that is not currently + * executing (ie the next runnable started will be the one given). + * <em>Note: <tt>preemptAndWait()</tt> must not be called from the + * current thread (for example from the <tt>run()</tt> method of the + * argument). + * @throws IllegalStateException if getThread() is null or if the + * thread returned by getThread() is the current one. + */ + public void preemptAndWait(Runnable r) throws InterruptedException { + if (runnableQueueThread == null) { + throw new IllegalStateException + ("RunnableQueue not started or has exited"); + } + if (runnableQueueThread == Thread.currentThread()) { + throw new IllegalStateException + ("Cannot be called from the RunnableQueue thread"); + } + + LockableLink l = new LockableLink(r); + synchronized (list) { + list.unpop(l); list.notify(); } l.lock(); 1.3 +37 -14 xml-batik/test-sources/org/apache/batik/util/RunnableQueueTest.java Index: RunnableQueueTest.java =================================================================== RCS file: /home/cvs/xml-batik/test-sources/org/apache/batik/util/RunnableQueueTest.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- RunnableQueueTest.java 2001/08/06 19:38:55 1.2 +++ RunnableQueueTest.java 2001/10/04 14:48:40 1.3 @@ -56,7 +56,7 @@ for (int i=0; i<nThreads; i++) { Runnable rqRable = new RQRable(i, rand.nextInt(50)+1); - l.add(new TPRable(rq, i, rand.nextBoolean(), + l.add(new TPRable(rq, i, rand.nextInt(4)+1, rand.nextInt(500)+1, 20, rqRable)); } @@ -102,41 +102,64 @@ } } + public static final int INVOKE_LATER = 1; + public static final int INVOKE_AND_WAIT = 2; + public static final int PREEMPT_LATER = 3; + public static final int PREEMPT_AND_WAIT = 4; + public class TPRable implements Runnable { + RunnableQueue rq; int idx; - boolean invokeAndWait; + int style; long repeatDelay; int count; Runnable rqRable; TPRable(RunnableQueue rq, int idx, - boolean invokeAndWait, + int style, long repeatDelay, int count, Runnable rqRable) { - this.rq = rq; - this.idx = idx; - this.invokeAndWait = invokeAndWait; - this.repeatDelay = repeatDelay; - this.count = count; - this.rqRable = rqRable; + this.rq = rq; + this.idx = idx; + this.style = style; + this.repeatDelay = repeatDelay; + this.count = count; + this.rqRable = rqRable; } public void run() { try { while (count-- != 0) { - if (invokeAndWait) { - System.out.println(" InvW #" + idx); - rq.invokeAndWait(rqRable); - System.out.println("Done InvW #" + idx); - } else { + switch (style) { + case INVOKE_LATER: synchronized (rqRable) { System.out.println(" InvL #" + idx); rq.invokeLater(rqRable); System.out.println("Done InvL #" + idx); rqRable.wait(); } + break; + case INVOKE_AND_WAIT: + System.out.println(" InvW #" + idx); + rq.invokeAndWait(rqRable); + System.out.println("Done InvW #" + idx); + break; + case PREEMPT_LATER: + synchronized (rqRable) { + System.out.println(" PreL #" + idx); + rq.preemptLater(rqRable); + System.out.println("Done PreL #" + idx); + rqRable.wait(); + } + break; + case PREEMPT_AND_WAIT: + System.out.println(" PreW #" + idx); + rq.preemptAndWait(rqRable); + System.out.println("Done PreW #" + idx); + break; } + if (repeatDelay < 0) break; Thread.sleep(repeatDelay);
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]