Hey Thanks Chris,  Awesome to see some contribution.

I committed something very similar last night, it could use some refactoring too, the only difference from what you have here is the TaskThread creates the thread in its constructor, but it doesn't start the thread in the constructor. I added an additional method TaskTread.start() to start the thread. It avoids the null reference and thread could be final, can't remember if I made the Thread reference final or not.

Oddly enough though , Hudson failed shortly after, so I'll need to investigate why, here's the Hudson web site:

http://hudson.zones.apache.org/hudson/view/River/job/River-trunk/

Cheers,

Peter.

Christopher Dolan wrote:
OK, sorry for the repeated messages. The list apparently doesn't allow
attachments...

--- TaskManager.java    2010-03-02 11:49:30.629703600 -0600
+++ TaskManager2.java   2010-06-08 11:11:54.309412900 -0500
@@ -190,10 +190,13 @@
        logAdd(t);  //DAS 6/06 add
        boolean poke = true;
        while (threads.size() < maxThreads && needThread()) {
-           Thread th;
+           TaskThread th;
            try {
                th = new TaskThread();
-               th.start();
+               Thread thread = new Thread(new TaskThread());
+               thread.setName("task");
+               thread.setDaemon(true);
+               thread.start();
            } catch (Throwable tt) {
                try {
                    logger.log(threads.isEmpty() ?
@@ -290,8 +293,8 @@
                    for (int j = threads.size(); --j >= 0; ) {
                        TaskThread thread = (TaskThread)threads.get(j);
                        if (thread.task == t) {
-                           if (thread != Thread.currentThread())
-                               thread.interrupt();
+                           if (thread.myThread !=
Thread.currentThread())
+                               thread.myThread.interrupt();
                            break;
                        }
                    }
@@ -327,15 +330,11 @@
        return maxThreads;
     }
- private class TaskThread extends Thread {
+    private class TaskThread implements Runnable {
/** The task being run, if any */
        public Task task = null;
-
-       public TaskThread() {
-           super("task");
-           setDaemon(true);
-       }
+       public Thread myThread = null;
/**
         * Find the next task that can be run, and mark it taken by
@@ -363,8 +362,9 @@
        }
public void run() {
+           myThread = Thread.currentThread();
            while (true) {
                synchronized (TaskManager.this) {
                    if (terminated)
                        return;
                    if (task != null) {
@@ -376,11 +376,11 @@
                            }
                        }
                        task = null;
-                       interrupted(); // clear interrupt bit
+                       myThread.interrupted(); // clear interrupt bit
                    }
                    if (!takeTask()) {
                        try {
                            TaskManager.this.wait(timeout);
                        } catch (InterruptedException e) {
                        }
                        if (terminated || !takeTask()) {


-----Original Message-----
From: Christopher Dolan [mailto:[email protected]] Sent: Tuesday, June 08, 2010 11:13 AM
To: [email protected]
Subject: RE: com.sun.jini.thread lock contention

Oops, let me try that patch one more time...
Chris


-----Original Message-----
From: Christopher Dolan Sent: Tuesday, June 08, 2010 11:11 AM
To: '[email protected]'
Subject: RE: com.sun.jini.thread lock contention

Attached is a minimalist initial patch.  I'm not happy that I had to
store a reference to the thread in the Runnable...  But otherwise I
wasn't sure how to interrupt it from removeTask() without a separate map
of TaskThread to Thread.  There's all a null pointer race in this patch
if you try to remove a task before it's run() method executes.

Chris


Reply via email to