aboutsummaryrefslogtreecommitdiff
path: root/libjava/win32-threads.cc
diff options
context:
space:
mode:
authorTom Tromey <tromey@gcc.gnu.org>2000-03-15 22:03:19 +0000
committerTom Tromey <tromey@gcc.gnu.org>2000-03-15 22:03:19 +0000
commit878885b41142dd76e858b1f705bd31f357a5acc5 (patch)
tree6ff411e4ce4a6ce8717905d98f2d63b7479a6539 /libjava/win32-threads.cc
parent1a7b4c697c6ea7b132db9fdb84d3c9ff97c48e19 (diff)
downloadgcc-878885b41142dd76e858b1f705bd31f357a5acc5.zip
gcc-878885b41142dd76e858b1f705bd31f357a5acc5.tar.gz
gcc-878885b41142dd76e858b1f705bd31f357a5acc5.tar.bz2
[multiple changes]
2000-03-15 Tom Tromey <tromey@cygnus.com> * java/io/natFileDescriptorWin32.cc (winerr): Now static. * prims.cc (win32_exception_handler): Reformatted. * include/win32-threads.h (_Jv_HaveCondDestroy): New define. (_Jv_HaveMutexDestroy): Likewise. 2000-03-15 Jon Beniston <jb7216@bristol.ac.uk> * java/io/natFileDescriptorWin32.cc: New file. * java/io/natFileWin32.cc: New file. * java/net/natInetAddress.cc: Added conditional inclusion of Windows / Winsock headers. * java/net/natPlainDatagramSocketImpl.cc: Added conditional inclusion of Windows / Winsock headers. * java/net/natPlainSocketImpl.cc: Added conditional inclusion of Windows / Winsock headers. * include/win32-signal.h: New file. * include/win32-threads.h: New file. * win32-threads.cc: New file. * exception.cc (win32_get_restart_frame): New function. * prims.cc (win32_exception_handler): New function. (main_init) Performs Winsock initialisation. (main_init) Installs exeception handler. From-SVN: r32567
Diffstat (limited to 'libjava/win32-threads.cc')
-rw-r--r--libjava/win32-threads.cc247
1 files changed, 247 insertions, 0 deletions
diff --git a/libjava/win32-threads.cc b/libjava/win32-threads.cc
new file mode 100644
index 0000000..9c6ae8c
--- /dev/null
+++ b/libjava/win32-threads.cc
@@ -0,0 +1,247 @@
+// win32-threads.cc - interface between libjava and Win32 threads.
+
+/* Copyright (C) 1998, 1999 Red Hat, Inc.
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+// If we're using the Boehm GC, then we need to override some of the
+// thread primitives. This is fairly gross.
+#ifdef HAVE_BOEHM_GC
+extern "C"
+{
+#include <boehm-config.h>
+#include <gc.h>
+};
+#endif /* HAVE_BOEHM_GC */
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/lang/Thread.h>
+#include <java/lang/System.h>
+
+#include <errno.h>
+
+#ifndef ETIMEDOUT
+#define ETIMEDOUT 116
+#endif
+
+// This is used to implement thread startup.
+struct starter
+{
+ _Jv_ThreadStartFunc *method;
+ java::lang::Thread *object;
+ _Jv_Thread_t *data;
+};
+
+// Controls access to the variable below
+static HANDLE daemon_mutex;
+static HANDLE daemon_cond;
+// Number of non-daemon threads - _Jv_ThreadWait returns when this is 0
+static int non_daemon_count;
+
+// TLS key get Java object representing the thread
+DWORD _Jv_ThreadKey;
+// TLS key to get _Jv_Thread_t* representing the thread
+DWORD _Jv_ThreadDataKey;
+
+//
+// These are the flags that can appear in _Jv_Thread_t.
+//
+
+// Thread started.
+#define FLAG_START 0x01
+// Thread is daemon.
+#define FLAG_DAEMON 0x02
+
+//
+// Condition variables.
+//
+
+int
+_Jv_CondWait (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, jlong millis, jint nanos)
+{
+ DWORD time;
+ DWORD rval;
+
+ _Jv_MutexUnlock (mu);
+
+ if((millis == 0) && (nanos > 0))
+ time = 1;
+ else if(millis == 0)
+ time = INFINITE;
+ else
+ time = millis;
+
+ rval = WaitForSingleObject (*cv, time);
+ _Jv_MutexLock (mu);
+
+ if (rval == WAIT_FAILED)
+ return GetLastError (); // FIXME: Map to errno?
+ else if (rval == WAIT_TIMEOUT)
+ return ETIMEDOUT;
+ else
+ return 0;
+}
+
+//
+// Mutexes.
+//
+
+int
+_Jv_MutexLock (_Jv_Mutex_t *mu)
+{
+ DWORD rval;
+
+ // FIXME: Are Win32 mutexs recursive? Should we use critical section objects
+ rval = WaitForSingleObject (*mu, INFINITE);
+
+ if (rval == WAIT_FAILED)
+ return GetLastError (); // FIXME: Map to errno?
+ else if (rval == WAIT_TIMEOUT)
+ return ETIMEDOUT;
+ else
+ return 0;
+}
+
+//
+// Threads.
+//
+
+void
+_Jv_InitThreads (void)
+{
+ _Jv_ThreadKey = TlsAlloc();
+ _Jv_ThreadDataKey = TlsAlloc();
+ daemon_mutex = CreateMutex(NULL, 0, NULL);
+ daemon_cond = CreateEvent(NULL, 0, 0, NULL);
+ non_daemon_count = 0;
+}
+
+void
+_Jv_ThreadInitData (_Jv_Thread_t **data, java::lang::Thread *)
+{
+ _Jv_Thread_t *info = new _Jv_Thread_t;
+ info->flags = 0;
+
+ // FIXME register a finalizer for INFO here.
+ // FIXME also must mark INFO somehow.
+
+ *data = info;
+}
+
+void
+_Jv_ThreadSetPriority (_Jv_Thread_t *data, jint prio)
+{
+ int actual = THREAD_PRIORITY_NORMAL;
+
+ if (data->flags & FLAG_START)
+ {
+ switch (prio)
+ {
+ case 10:
+ actual = THREAD_PRIORITY_TIME_CRITICAL;
+ break;
+ case 9:
+ actual = THREAD_PRIORITY_HIGHEST;
+ break;
+ case 8:
+ case 7:
+ actual = THREAD_PRIORITY_ABOVE_NORMAL;
+ break;
+ case 6:
+ case 5:
+ actual = THREAD_PRIORITY_NORMAL;
+ break;
+ case 4:
+ case 3:
+ actual = THREAD_PRIORITY_BELOW_NORMAL;
+ break;
+ case 2:
+ actual = THREAD_PRIORITY_LOWEST;
+ break;
+ case 1:
+ actual = THREAD_PRIORITY_IDLE;
+ break;
+ }
+ SetThreadPriority(data->handle, actual);
+ }
+}
+
+// This function is called when a thread is started. We don't arrange
+// to call the `run' method directly, because this function must
+// return a value.
+static DWORD __stdcall
+really_start (void* x)
+{
+ struct starter *info = (struct starter *) x;
+
+ TlsSetValue (_Jv_ThreadKey, info->object);
+ TlsSetValue (_Jv_ThreadDataKey, info->data);
+ info->method (info->object);
+
+ if (! (info->data->flags & FLAG_DAEMON))
+ {
+ WaitForSingleObject (daemon_mutex, INFINITE);
+ non_daemon_count--;
+ if (! non_daemon_count)
+ PulseEvent (daemon_cond);
+ ReleaseMutex (daemon_mutex);
+ }
+
+ return 0;
+}
+
+void
+_Jv_ThreadStart (java::lang::Thread *thread, _Jv_Thread_t *data, _Jv_ThreadStartFunc *meth)
+{
+ DWORD id;
+ struct starter *info;
+
+ // Do nothing if thread has already started
+ if (data->flags & FLAG_START)
+ return;
+ data->flags |= FLAG_START;
+
+ // FIXME: handle marking the info object for GC.
+ info = (struct starter *) _Jv_AllocBytes (sizeof (struct starter));
+ info->method = meth;
+ info->object = thread;
+ info->data = data;
+
+ if (! thread->isDaemon ())
+ {
+ WaitForSingleObject (daemon_mutex, INFINITE);
+ non_daemon_count++;
+ ReleaseMutex (daemon_mutex);
+ }
+ else
+ data->flags |= FLAG_DAEMON;
+
+ HANDLE h = CreateThread(NULL, 0, really_start, info, 0, &id);
+ _Jv_ThreadSetPriority(data, thread->getPriority());
+
+ //if (!h)
+ //JvThrow ();
+}
+
+void
+_Jv_ThreadWait (void)
+{
+ WaitForSingleObject(daemon_mutex, INFINITE);
+ if(non_daemon_count)
+ SignalObjectAndWait(daemon_mutex, daemon_cond, INFINITE, 0);
+ ReleaseMutex(daemon_mutex);
+}
+
+void
+_Jv_ThreadInterrupt (_Jv_Thread_t *data)
+{
+ MessageBox(NULL, "Unimplemented", "win32-threads.cc:_Jv_ThreadInterrupt", MB_OK);
+ // FIXME:
+}