This commit is contained in:
jfrijters 2003-07-29 10:27:31 +00:00
Родитель 9f53b67ba8
Коммит f147a33b70
4 изменённых файлов: 1081 добавлений и 887 удалений

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

@ -980,26 +980,6 @@ namespace NativeCode.java
}
}
public class Thread
{
public static void sleep(long millis, int nanos)
{
NetSystem.Threading.Thread.Sleep(new TimeSpan(millis * 10000 + (nanos + 99) / 100));
}
public static void joinInternal(NetSystem.Threading.Thread nativeThread, long millis, int nanos)
{
if(millis == 0 && nanos == 0)
{
nativeThread.Join();
}
else
{
nativeThread.Join(new TimeSpan(millis * 10000 + (nanos + 99) / 100));
}
}
}
public class VMClass
{
private static Hashtable map = new Hashtable();

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

@ -4,6 +4,7 @@ C:\ikvm\classpath\gnu\classpath\Configuration.java
C:\ikvm\classpath\gnu\java\net\protocol\ikvmres\Handler.java
C:\ikvm\classpath\java\io\FileDescriptor.java
C:\ikvm\classpath\java\lang\Thread.java
C:\ikvm\classpath\java\lang\VMThread.java
C:\ikvm\classpath\java\lang\VMClass.java
C:\ikvm\classpath\java\lang\VMDouble.java
C:\ikvm\classpath\java\lang\VMFloat.java

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -0,0 +1,307 @@
package java.lang;
// Note: stop() should take care not to stop a thread if it is
// executing code in this class.
final class VMThread
{
// Note: when this thread dies, this reference is *not* cleared
volatile Thread thread;
private volatile boolean running;
private VMThread(Thread thread)
{
this.thread = thread;
}
private void run()
{
try
{
try
{
running = true;
synchronized(thread)
{
Throwable t = thread.stillborn;
if(t != null)
{
thread.stillborn = null;
throw t;
}
}
thread.run();
}
catch(Throwable t)
{
try
{
thread.group.uncaughtException(thread, t);
}
catch(Throwable ignore)
{
}
}
}
finally
{
// Setting runnable to false is partial protection against stop
// being called while we're cleaning up. To be safe all code in
// VMThread be unstoppable.
running = false;
thread.die();
synchronized(this)
{
// release the threads waiting to join us
notifyAll();
}
}
}
static void create(Thread thread, long stacksize)
{
VMThread vmThread = new VMThread(thread);
vmThread.start(stacksize);
thread.vmThread = vmThread;
}
String getName()
{
return thread.name;
}
void setName(String name)
{
thread.name = name;
}
void setPriority(int priority)
{
thread.priority = priority;
nativeSetPriority(priority);
}
int getPriority()
{
synchronized(thread)
{
return thread.priority;
}
}
boolean isDaemon()
{
return thread.daemon;
}
int countStackFrames()
{
return 0;
}
synchronized void join(long ms, int ns) throws InterruptedException
{
// We use the VMThread object to wait on, because this is a private
// object, so client code cannot call notify on us.
wait(ms, ns);
}
void stop(Throwable t)
{
// Note: we assume that we own the lock on thread
// (i.e. that Thread.stop() is synchronized)
if(running)
nativeStop(t);
else
thread.stillborn = t;
}
private static system.LocalDataStoreSlot localDataStoreSlot = system.threading.Thread.AllocateDataSlot();
private system.threading.Thread nativeThread;
/*native*/ void start(long stacksize)
{
system.threading.ThreadStart starter = new system.threading.ThreadStart(
new system.threading.ThreadStart.Method()
{
public void Invoke()
{
system.threading.Thread.SetData(localDataStoreSlot, thread);
run();
}
});
nativeThread = new system.threading.Thread(starter);
nativeThread.set_Name(thread.name);
nativeThread.set_IsBackground(thread.daemon);
nativeSetPriority(thread.priority);
nativeThread.Start();
}
/*native*/ void interrupt()
{
nativeThread.Interrupt();
}
/*native*/ boolean isInterrupted()
{
// NOTE special case for current thread, because then we can use the .NET interrupted status
if(thread == currentThread())
{
try
{
if(false) throw new InterruptedException();
system.threading.Thread.Sleep(0);
return false;
}
catch(InterruptedException x)
{
// because we "consumed" the interrupt, we need to interrupt ourself again
nativeThread.Interrupt();
return true;
}
}
// HACK since quering the interrupted state of another thread is inherently racy, I hope
// we can get away with always returning false, because I have no idea how to obtain this
// information from the .NET runtime
return false;
}
/*native*/ void suspend()
{
nativeThread.Suspend();
}
/*native*/ void resume()
{
nativeThread.Resume();
}
/*native*/ void nativeSetPriority(int priority)
{
if(priority == Thread.MIN_PRIORITY)
{
nativeThread.set_Priority(system.threading.ThreadPriority.Lowest);
}
else if(priority > Thread.MIN_PRIORITY && priority < Thread.NORM_PRIORITY)
{
nativeThread.set_Priority(system.threading.ThreadPriority.BelowNormal);
}
else if(priority == Thread.NORM_PRIORITY)
{
nativeThread.set_Priority(system.threading.ThreadPriority.Normal);
}
else if(priority > Thread.NORM_PRIORITY && priority < Thread.MAX_PRIORITY)
{
nativeThread.set_Priority(system.threading.ThreadPriority.AboveNormal);
}
else if(priority == Thread.MAX_PRIORITY)
{
nativeThread.set_Priority(system.threading.ThreadPriority.Highest);
}
}
/*native*/ void nativeStop(Throwable t)
{
nativeThread.Abort(t);
}
/*native*/ static Thread currentThread()
{
Thread javaThread = (Thread)system.threading.Thread.GetData(localDataStoreSlot);
if(javaThread == null)
{
// threads created outside of Java always run in the root thread group
system.threading.Thread nativeThread = system.threading.Thread.get_CurrentThread();
VMThread vmThread = new VMThread(null);
vmThread.nativeThread = nativeThread;
int priority = Thread.NORM_PRIORITY;
switch(nativeThread.get_Priority())
{
case system.threading.ThreadPriority.Lowest:
priority = Thread.MIN_PRIORITY;
break;
case system.threading.ThreadPriority.BelowNormal:
priority = 3;
break;
case system.threading.ThreadPriority.Normal:
priority = Thread.NORM_PRIORITY;
break;
case system.threading.ThreadPriority.AboveNormal:
priority = 7;
break;
case system.threading.ThreadPriority.Highest:
priority = Thread.MAX_PRIORITY;
break;
}
javaThread = new Thread(vmThread, nativeThread.get_Name(), priority, nativeThread.get_IsBackground());
vmThread.thread = javaThread;
system.threading.Thread.SetData(localDataStoreSlot, javaThread);
javaThread.group = ThreadGroup.root;
javaThread.group.addThread(javaThread);
InheritableThreadLocal.newChildThread(javaThread);
}
return javaThread;
}
static /*native*/ void yield()
{
system.threading.Thread.Sleep(0);
}
static /*native*/ void sleep(long ms, int ns) throws InterruptedException
{
try
{
if(false) throw new system.threading.ThreadInterruptedException();
// TODO guard against ms and ns overflowing
system.threading.Thread.Sleep(new system.TimeSpan(ms * 10000 + (ns + 99) / 100));
}
catch(system.threading.ThreadInterruptedException x)
{
throw new InterruptedException(x.get_Message());
}
}
static /*native*/ boolean interrupted()
{
try
{
synchronized(currentThread())
{
if(false) throw new InterruptedException();
system.threading.Thread.Sleep(0);
}
return false;
}
catch(InterruptedException x)
{
return true;
}
}
static /*native*/ boolean holdsLock(Object obj)
{
if(obj == null)
{
throw new NullPointerException();
}
try
{
// HACK this is a lame way of doing this, but I can't see any other way
// NOTE Wait causes the lock to be released temporarily, which isn't what we want
if(false) throw new IllegalMonitorStateException();
if(false) throw new InterruptedException();
system.threading.Monitor.Wait(obj, 0);
return true;
}
catch(IllegalMonitorStateException x)
{
return false;
}
catch(InterruptedException x1)
{
// Since we "consumed" the interrupt, we have to interrupt ourself again
system.threading.Thread.get_CurrentThread().Interrupt();
return true;
}
}
}