|
Evaluation
|
As a workaround, an "@ignore" tag has been added to the test so that
it is not run.
I can't reproduce this hang on fyi, but...
By inspection, there is a race condition wherein it is assumed that all
the transformers will added before the transformer removing threads
will run. When this false assumption is violated, all the transformers
don't get removed and the test waits forever for this to occur.
I'm not sure the test is useful, this should be invaluated before an
attempted fix.
xxxxx@xxxxx 2003-09-23
This test launches:
- a single thread (execThread) to cause transformers to be
executed by calling redefineClasses() in a loop
- multiple threads to add transformers
- multiple threads to remove transformers
The main thread sits in a very tight loop:
while (!testCompleted())
{
Thread.currentThread().yield();
}
The above yield() call doesn't really do anything
on Linux if I remember correctly so the main thread
could be swamping the machine here...
testCompleted() is:
protected boolean
testCompleted()
{
return getExecThread().fDone;
}
which means the main thread is constantly querying
the ExecuteTransformersThread.fDone field. So the
main thread will pound away as long as the execThread
thinks it has work to do...
The ExecuteTransformersThread is in a slightly less
tight loop:
while(!threadsDone())
{
executeTransform();
}
// Do a final check for good measure
executeTransform();
fDone = true;
threadsDone() is:
protected boolean
threadsDone()
{
return fFinished == TOTAL_THREADS;
}
TOTAL_THREADS is the number of "add transformer"
threads.
fFinished is incremented by a synchronized function:
protected synchronized void
threadFinished(Thread t)
{
fFinished++;
}
fFinished is initialized to zero by the test scaffold
setup code before any threads are launched. So the
execThread will sit in its loop until all of the "add
transformer" threads have finished.
Once the execThread completes, that will permit the
main thread to complete and the test will finished.
So that's the theory of how this test works...
The previous eval comment mentions the following race:
> By inspection, there is a race condition wherein it is
> assumed that all the transformers will added before the
> transformer removing threads will run. When this false
> assumption is violated, all the transformers don't get
> removed and the test waits forever for this to occur.
I don't see where the test waits for all of the transformers
to be removed. I do see there a "remove thread" will sit in
a loop removing transformers until all the "add threads"
have finished executing, but that's about it.
I believe the "hard hang" reported in the description is due
to the really tight loop that the main thread is in with this
test. That style of tight loop has been a problem on Linux
machines.
Also note that TransformerManagementThreadAddTests.java also
has a similar tight loop for the main thread.
Posted Date : 2008-02-13 01:48:17.0
Both of these test sources:
TransformerManagementThreadAddTests.java
TransformerManagementThreadRemoveTests.java
violate a couple of the guidelines from "Effective Java":
Item 48: Synchronize access to shared mutable data
Don't use a direct field getter
Don't use a direct field setter
Item 51: Don't depend on the thread scheduler
Use sleep() instead of yield()
The code in the evaluation entry #2 gives examples of
the actual violations. With these items fixed, this test
should be much better behaved on Linux machines.
Posted Date : 2008-02-14 03:39:07.0
|