find_class() can be called by on a class which is being loaded by the
same thread which is loading the class. This happens when class
loading is delegated to external class loaders. We should handle this
by returning NULL so that external class loader will actually load the
class.

Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 vm/classloader.c |   17 +++++++++++++++--
 1 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/vm/classloader.c b/vm/classloader.c
index fecb48f..28270c7 100644
--- a/vm/classloader.c
+++ b/vm/classloader.c
@@ -15,6 +15,7 @@
 #include "vm/class.h"
 #include "vm/die.h"
 #include "vm/backtrace.h"
+#include "vm/thread.h"
 #include "vm/trace.h"
 
 #include "lib/string.h"
@@ -199,6 +200,7 @@ struct classloader_class {
 
        /* number of threads waiting for a class. */
        unsigned long nr_waiting;
+       struct vm_thread *loading_thread;
 };
 
 static struct hash_map *classes;
@@ -518,8 +520,18 @@ static struct classloader_class *find_class(const char 
*name)
        class = lookup_class(name);
        if (class) {
                /*
-                * If class is being loaded by another thread then wait
-                * until loading is completed.
+                * If class is being loaded by current thread then we
+                * should return NULL. We do this because class
+                * loading might be delegated to external class
+                * loaders which might query the VM before loading.
+                */
+               if (class->status == CLASS_LOADING &&
+                   class->loading_thread == vm_thread_self())
+                       return NULL;
+
+               /*
+                * If class is being loaded by another thread then
+                * wait until loading is completed.
                 */
 
                ++class->nr_waiting;
@@ -572,6 +584,7 @@ classloader_load(struct vm_object *loader, const char 
*class_name)
 
        class = malloc(sizeof(*class));
        class->status = CLASS_LOADING;
+       class->loading_thread = vm_thread_self();
 
        if (hash_map_put(classes, strdup(slash_class_name), class)) {
                vmc = NULL;
-- 
1.6.0.6


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to