Posted: Wed Oct 08, 2003 8:05 pm Post subject: Java 1.4.1 breakthrough
While I was uploading the NeoOffice/J 0.7 binaries today, I tried running NeoJ with Java 1.4.1 enabled. Some of you might recall that I tried this a couple of months ago and Java would crash nearly 100% of the time.
Well, I figured out what was causing Java 1.4.1 to crash: detaching a thread from the JVM! Normally, using JNI you can attach and detach a thread to the JVM mutliple times (and both OOo and NeoJ do so). However, with Java 1.4.1 on Mac OS X, detaching and then attaching a thread really confuses the JVM (clearly a bug in my opinion). By commenting out the detaching code, I got NeoJ to actually run!
Not surprisingly, some font and drawing issues exist when I used Java 1.4.1 (Java seems to want to constantly draw the background color to a window), but the really cool thing that I noticed was that text, shape, and line drawing are incredibly fast.
When I say "incredibly fast", I noticed double or triple the speed of drawing in Java 1.3.1. For example, in Jim Laurent's document, some painting operations (like moving the floating style window) take a full 3 seconds on my machine. Using Java 1.4.1, this operation takes only a second.
Joined: May 25, 2003 Posts: 4752 Location: Santa Barbara, CA
Posted: Thu Oct 09, 2003 12:19 am Post subject:
Whoah! Dude, very cool news! I'm shocked you found that one...truly bizarre.
I'm not up on my JNI interface and especially not threading with JNI or embedded VMs. Quick thought, however...if the crash is on attaching a thread and not detatching the thread, the problem may be related to NSAutoreleasePools. Each thread in a Cocoa app that's not an NSThread originally needs to have an NSAutoreleasePool constructed for that thread. I'm assuming that the 1.4.1 VM is making cocoa calls on some of these threads...and I know I have to do this for pthreads in Neo...
Is there any way in JNI to "trap" a thread before it gets attached to execute some code? The big problem is that the NSAutoreleasePool needs to be created while the thread is executing...it can't be created from another thread
NSThread also has some other wonky overhead that's hidden from the programmer (it's for our benefit, or so they say...) but on 10.2 systems I've found pthreads with autorelease pools are mostly stable. It's still not documented which calls won't work on pthreads, but hey, what can you do
Whoah! Dude, very cool news! I'm shocked you found that one...truly bizarre.
Well, I just kept commenting out code until something worked. Of course, I spent two solid weeks on this back in August in order to find it this time around.
OPENSTEP wrote:
I'm not up on my JNI interface and especially not threading with JNI or embedded VMs. Quick thought, however...if the crash is on attaching a thread and not detatching the thread, the problem may be related to NSAutoreleasePools. Each thread in a Cocoa app that's not an NSThread originally needs to have an NSAutoreleasePool constructed for that thread. I'm assuming that the 1.4.1 VM is making cocoa calls on some of these threads...and I know I have to do this for pthreads in Neo...
In NeoJ, the crash always happens when Java's java.awt.* class invoke native Cocoa calls (most of java.awt.* is native code). These calss after after an attach and before a detach.
Given the above facts, I think you may be on to something. It could be that Java's detach function is releasing an NSAutoreleasePool. Then, when I attach the same thread later and try to use the same Java object pointers (which presumably wrapper Cocoa object references), the Cocoa object references are no longer since they were released in the last detach.
OPENSTEP wrote:
Is there any way in JNI to "trap" a thread before it gets attached to execute some code? The big problem is that the NSAutoreleasePool needs to be created while the thread is executing...it can't be created from another thread
I was already thinking about how to do this. Fortunately, the attach and detach functions are members of a JavaVM struct. This struct gets initialized by a call to JNI_CreateJavaVM in the stoc/source/javavm code (i.e. the JavaVM UNO service). What I can do is replace the attach and detach function pointers in the JavaVM struct with my own functions that live inside the JavaVM UNO service before I return the JavaVM struct to the calling module (e.g. vcl, bridges, connectivity, etc.).
I am thinking that the replacement detach function would do nothing. Instead, I would have the replacement attach invoke pthread_cleanup_push() to have the real detach function execute when the current thread exits.
If this approach works, no changes to the code outside of the stoc/source/javavm directory would be needed.
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum