Update of /cvsroot/freenet/freenet/src/freenet
In directory sc8-pr-cvs1:/tmp/cvs-serv8270/src/freenet

Modified Files:
        Ticker.java 
Log Message:
Run fast/immediate messages on a dedicated thread within the ticker instead of letting 
the scheduling thread run them

Index: Ticker.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/Ticker.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- Ticker.java 14 Oct 2003 00:43:14 -0000      1.21
+++ Ticker.java 14 Oct 2003 16:32:08 -0000      1.22
@@ -42,6 +42,8 @@
     private final Heap events = new Heap();
     private final MessageHandler mh;
     private final ThreadFactory tf;
+    private final int desiredMaximumImmediateExecutionQueueSize = 2000; //TODO: 
Hadcoded
+    private ImmediateMessageExecutionThread immediateExecutionThread = new 
ImmediateMessageExecutionThread(desiredMaximumImmediateExecutionQueueSize); //TODO: 
Hadcoded
 
     //private long maxTaskWaitMs = 30000;
 
@@ -55,6 +57,7 @@
     public Ticker(MessageHandler mh, ThreadFactory tf) {
         this.mh = mh;
         this.tf = tf;
+        immediateExecutionThread.start();
     }
 
     /**
@@ -63,7 +66,7 @@
     public final MessageHandler getMessageHandler() {
         return mh;
     }
-
+    
     /**
      * Schedules a MessageObject.
      * @param time  The time to wait (in milliseconds) before handling the 
@@ -81,12 +84,22 @@
                }
         addAbs(time + System.currentTimeMillis(), mo);
     }
+    
+       /**
+        * Run the event on the immediate execution thread if possible (@see 
StandardMessageHandler.handle)
+        * unless there are too many events enqueued there already in which case the 
calling
+        * thread itself will be used to execute the event
+        */
+       public final void addNowOrRun(MessageObject mo) {
+               if(!immediateExecutionThread.enqueue(mo))
+                       runOrSchedule(mo);
+       }
        
        /**
         * Run the event immediately if possible (@see StandardMessageHandler.handle)
         * Otherwise add(now, mo)
         */
-       public final void addNowOrRun(MessageObject mo) {
+       private final void runOrSchedule(MessageObject mo) {
                try {
                        if(!mh.handle(mo, true)) add(0, mo);
                } catch (Throwable t) {
@@ -221,7 +234,10 @@
     public synchronized void writeEventsHtml(PrintWriter pw) {
         pw.println("<h2>Fred Ticker Contents</h2> <b>At date:");
         pw.println(new Date());
-        pw.println("</b><table border=1>");
+        pw.println("</b><br>");
+        immediateExecutionThread.writeEventsHtml(pw);
+
+        pw.println("<br><b>Pending tasks ("+events.size()+")</b><table border=1>");
         pw.println("<tr><th>Time</th><th>Event</th></tr>");
         Heap.Element[] el = events.elementArray();
         QuickSorter.quickSort(new ArraySorter(el));
@@ -324,6 +340,56 @@
             return mo;
         }
     }
+       protected class ImmediateMessageExecutionThread extends Thread {
+               private BlockingQueue immediateExecutionQueue = new BlockingQueue();
+
+               //The maximum number of events to allow in the queue.
+               //Might be overshot.
+               private int desiredMaximumQueue;
+               ImmediateMessageExecutionThread(int desiredMaximumQueue) {
+                       super("Ticker immediate execution thread");
+                       this.setDaemon(true);
+                       this.desiredMaximumQueue = desiredMaximumQueue;
+               }
+               public int getCurrentQueueSize(){
+                       return immediateExecutionQueue.size();
+               }
+               //Enqueue the message for execution.
+               //Returns false if the thread already has too much work enqueued 
+               public boolean enqueue(MessageObject mo){
+                       //No synch here since we are allowed to oovershoot the limit 
by a couple of
+                       //events or so..
+                       if(immediateExecutionQueue.size()<desiredMaximumQueue){ 
+                               immediateExecutionQueue.enqueue(mo);
+                               return true;
+                       }else
+                               return false;
+               }
+               public void run() {
+                       while(true) {
+                               try{
+                                       Object o = immediateExecutionQueue.dequeue();
+                                       runOrSchedule((MessageObject)o);
+                               }catch(InterruptedException e){}
+                       }
+               }
+               public void writeEventsHtml(PrintWriter pw){
+                       pw.println("<b>Pending immediate execution tasks (Count: 
"+immediateExecutionThread.getCurrentQueueSize()+", Desired max: 
"+desiredMaximumQueue+")</b>");
+                       pw.println("<table 
border=1><tr><th>Time</th><th>Event</th></tr>");
+                       
+                       Object[] events = immediateExecutionQueue.toArray();
+                       for (int i = 0 ; i < events.length ; i++) {
+                               pw.print("<tr><td>"); 
+                               Event ev =(Event) events[i];
+                               pw.print(new Date(ev.time()));
+                               pw.print("</td><td>");
+                               pw.print(ev.mo);
+                               pw.println("</td></tr>");
+                       }
+                       pw.println("</table>");
+                       
+               }
+       }
 }
 
 

_______________________________________________
cvs mailing list
[EMAIL PROTECTED]
http://dodo.freenetproject.org/cgi-bin/mailman/listinfo/cvs

Reply via email to