Added clean up for attached threads.

This commit is contained in:
jfrijters 2007-06-05 09:57:09 +00:00
Родитель 0f1840aa0d
Коммит dcfacece5c
2 изменённых файлов: 42 добавлений и 16 удалений

Просмотреть файл

@ -999,7 +999,7 @@ namespace IKVM.Runtime
// TODO if we set Thread.IsBackground to false when we attached, now might be a good time to set it back to true.
JNIEnv.FreeJNIEnv();
#if OPENJDK
IKVM.NativeCode.java.lang.Thread.DetachThreadFromJni();
IKVM.NativeCode.java.lang.Thread.DetachThread();
#else
JVM.Library.jniDetach();
#endif

Просмотреть файл

@ -1423,6 +1423,8 @@ namespace IKVM.NativeCode.java
{
[ThreadStatic]
private static VMThread vmThread;
[ThreadStatic]
private static object cleanup;
private static readonly System.Reflection.ConstructorInfo threadConstructor1;
private static readonly System.Reflection.ConstructorInfo threadConstructor2;
private static readonly System.Reflection.FieldInfo vmThreadField;
@ -1553,17 +1555,32 @@ namespace IKVM.NativeCode.java
}
finally
{
threadExitMethod.Invoke(javaThread, null);
threadStatusField.SetValue(javaThread, TERMINATED);
lock (javaThread)
{
System.Threading.Monitor.PulseAll(javaThread);
}
DetachThread();
}
#endif
}
}
private sealed class Cleanup
{
private object javaThread;
internal Cleanup(object javaThread)
{
this.javaThread = javaThread;
}
~Cleanup()
{
threadExitMethod.Invoke(javaThread, null);
threadStatusField.SetValue(javaThread, TERMINATED);
lock (javaThread)
{
System.Threading.Monitor.PulseAll(javaThread);
}
}
}
#if !FIRST_PASS
static Thread()
{
@ -1630,6 +1647,7 @@ namespace IKVM.NativeCode.java
t.running = true;
vmThreadField.SetValue(thread, t);
vmThread = t;
cleanup = new Cleanup(thread);
threadPriorityField.SetValue(thread, MapNativePriorityToJava(t.nativeThread.Priority));
if (name == null)
{
@ -1766,7 +1784,7 @@ namespace IKVM.NativeCode.java
public static int countStackFrames(object thisThread)
{
throw new NotImplementedException();
return 0;
}
public static bool holdsLock(object obj)
@ -1780,7 +1798,7 @@ namespace IKVM.NativeCode.java
}
try
{
// The new 1.5 memory model explicitly allows spurious wake-ups from Object.wait,
// The 1.5 memory model (JSR133) explicitly allows spurious wake-ups from Object.wait,
// so we abuse Pulse to check if we own the monitor.
System.Threading.Monitor.Pulse(obj);
return true;
@ -1923,7 +1941,7 @@ namespace IKVM.NativeCode.java
}
// this is called from JniInterface.cs
internal static void DetachThreadFromJni()
internal static void DetachThread()
{
object javaThread = currentThread();
threadExitMethod.Invoke(javaThread, null);
@ -1942,21 +1960,29 @@ namespace IKVM.NativeCode.java
{
throw new jlNullPointerException();
}
if (timeout < 0 || nanos < 0 || nanos > 999999)
if (timeout < 0)
{
throw new jlIllegalArgumentException("argument out of range");
throw new jlIllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999)
{
throw new jlIllegalArgumentException("nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && timeout == 0))
{
timeout++;
}
VMThread t = CurrentVMThread();
t.EnterInterruptableWait(timeout != 0 || nanos != 0);
t.EnterInterruptableWait(timeout != 0);
try
{
if ((timeout == 0 && nanos == 0) || timeout > 922337203685476L)
if (timeout == 0 || timeout > 922337203685476L)
{
System.Threading.Monitor.Wait(o);
}
else
{
System.Threading.Monitor.Wait(o, new System.TimeSpan(timeout * 10000 + (nanos + 99) / 100));
System.Threading.Monitor.Wait(o, new System.TimeSpan(timeout * 10000));
}
}
finally
@ -1972,7 +1998,7 @@ namespace IKVM.NativeCode.java
// this method has the wrong name, it is only called by ikvm.runtime.Startup.exitMainThread()
public static void jniDetach()
{
Thread.DetachThreadFromJni();
Thread.DetachThread();
}
public static void park(Object blocker, long nanos)