Here's what the JNI spec says about it:
MonitorExit
Prototype jint MonitorExit(JNIEnv *env, jobject obj);
...
Native code must not use MonitorExit to exit a monitor entered through a synchronized method or a monitorenter Java virtual machine instruction.
So, the current AWT code clearly does something that the JNI spec does not allow for.
As for structured locking, it isn't obvious to me that a VM "may not" impose it on monitors of "native" frames. This could be the subject of a long debate, which is not needed here, as the JNI spec has different provisions that forces a redesign of the current algorithm.
In general, writing unstructured locks is a recipe for getting into trouble (deadlocks, illegal monitor states, etc). Depending on a "depth 1" is a trouble in itself, as there's nothing preventing deeper locking depth on java (& JNI) monitors. If such "weird" thing is required, I would suggest to simply build the required locks a "self preserving" higher-level constructs.
e.g.
class OneLevelLock { private Object internalMonitor = new Object(); private Thread owner = null;
public lock() { synchronized(internalMonitor) { if (owner != null) throw IllegalMonitorState( "attempt to lock deeply");
owner = Thread.getCurrentThread(); } ...
and use JNI to call the lock/unlock methods of this "robust" one-level lock (for which structured locking is not required).
Etienne
Bryce McKinlay wrote:
iterateNativeQueue() needs to behave like wait(), because we need to allow threads to post events to the Java event queue while the EventDispatchThread is blocked in the GTK main loop. gtk_main_iteration could potentially block forever if there is no human/external event input, so other threads wishing to post events to the queue will block. For example: if the lock is not released, a thread drawing animations based on a timer wouldn't work correctly unless there is constant GTK event input because the "animation thread" would be blocked on postEvent().
I agree this approach is flakey, though - it isn't going to work if the queue lock is held at (depth > 1), and currently that is possible because it is a user-visible lock.
Certainly, bytecode isn't allowed to do this kind of thing, but I'm not sure if the structured locking rules in the VM spec are meant to apply to native code. For example, wait() would be impossible to implement if this were the case, wouldn't it?
Bryce
-- Etienne M. Gagnon, Ph.D. http://www.info2.uqam.ca/~egagnon/ SableVM: http://www.sablevm.org/ SableCC: http://www.sablecc.org/
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Classpath mailing list Classpath@gnu.org http://lists.gnu.org/mailman/listinfo/classpath