[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
This commit is contained in:
parent
1a7b4c697c
commit
878885b411
11 changed files with 1031 additions and 2 deletions
|
@ -1,3 +1,30 @@
|
||||||
|
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.
|
||||||
|
|
||||||
2000-03-14 Tom Tromey <tromey@cygnus.com>
|
2000-03-14 Tom Tromey <tromey@cygnus.com>
|
||||||
|
|
||||||
* jni.cc (mangled_name): Fixed assertion.
|
* jni.cc (mangled_name): Fixed assertion.
|
||||||
|
|
|
@ -37,7 +37,7 @@ extern "C" void __throw () __attribute__ ((__noreturn__));
|
||||||
extern "C" void __sjthrow () __attribute__ ((__noreturn__));
|
extern "C" void __sjthrow () __attribute__ ((__noreturn__));
|
||||||
extern "C" short __get_eh_table_version (void *table);
|
extern "C" short __get_eh_table_version (void *table);
|
||||||
extern "C" short __get_eh_table_language (void *table);
|
extern "C" short __get_eh_table_language (void *table);
|
||||||
|
extern "C" void *__get_eh_context ();
|
||||||
|
|
||||||
extern "C" void *
|
extern "C" void *
|
||||||
_Jv_type_matcher (java_eh_info *info, void* match_info,
|
_Jv_type_matcher (java_eh_info *info, void* match_info,
|
||||||
|
@ -161,3 +161,36 @@ _Jv_Throw (void *value)
|
||||||
__throw ();
|
__throw ();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_WIN32_SIGNALLING
|
||||||
|
|
||||||
|
// This is a mangled version of _Jv_Throw and __sjthrow except
|
||||||
|
// rather than calling longjmp, it returns a pointer to the jmp buffer
|
||||||
|
|
||||||
|
extern "C" int *
|
||||||
|
win32_get_restart_frame (void *value)
|
||||||
|
{
|
||||||
|
struct eh_context *eh = (struct eh_context *)__get_eh_context ();
|
||||||
|
void ***dhc = &eh->dynamic_handler_chain;
|
||||||
|
|
||||||
|
java_eh_info *ehinfo = *(__get_eh_info ());
|
||||||
|
if (ehinfo == NULL)
|
||||||
|
{
|
||||||
|
_Jv_eh_alloc ();
|
||||||
|
ehinfo = *(__get_eh_info ());
|
||||||
|
}
|
||||||
|
ehinfo->eh_info.match_function = (__eh_matcher) _Jv_type_matcher;
|
||||||
|
ehinfo->eh_info.language = EH_LANG_Java;
|
||||||
|
ehinfo->eh_info.version = 1;
|
||||||
|
ehinfo->value = value;
|
||||||
|
|
||||||
|
// FIXME: Run clean ups?
|
||||||
|
|
||||||
|
int *jmpbuf = (int*)&(*dhc)[2];
|
||||||
|
|
||||||
|
*dhc = (void**)(*dhc)[0];
|
||||||
|
|
||||||
|
return jmpbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* USE_WIN32_SIGNALLING */
|
||||||
|
|
43
libjava/include/win32-signal.h
Normal file
43
libjava/include/win32-signal.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
// win32-signal.h - Catch runtime signals and turn them into exceptions.
|
||||||
|
|
||||||
|
/* Copyright (C) 1998, 1999 Free Software Foundation
|
||||||
|
|
||||||
|
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. */
|
||||||
|
|
||||||
|
// Exception handling is done totally differently on Win32 this stuff
|
||||||
|
// just keeps it compatible
|
||||||
|
|
||||||
|
#ifndef JAVA_SIGNAL_H
|
||||||
|
#define JAVA_SIGNAL_H 1
|
||||||
|
|
||||||
|
#define HANDLE_SEGV 1
|
||||||
|
#define HANDLE_FPE 1
|
||||||
|
|
||||||
|
#define SIGNAL_HANDLER(_name) \
|
||||||
|
static void _name (int _dummy)
|
||||||
|
|
||||||
|
#define MAKE_THROW_FRAME do {} while (0)
|
||||||
|
#define HANDLE_DIVIDE_OVERFLOW do {} while (0)
|
||||||
|
|
||||||
|
#define INIT_SEGV \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
nullp = new java::lang::NullPointerException (); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
|
||||||
|
#define INIT_FPE \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
arithexception = new java::lang::ArithmeticException \
|
||||||
|
(JvNewStringLatin1 ("/ by zero")); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* JAVA_SIGNAL_H */
|
138
libjava/include/win32-threads.h
Normal file
138
libjava/include/win32-threads.h
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
// -*- c++ -*-
|
||||||
|
// win32-threads.h - Defines for using Win32 threads.
|
||||||
|
|
||||||
|
/* Copyright (C) 1998, 1999, 2000 Free Software Foundation
|
||||||
|
|
||||||
|
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. */
|
||||||
|
|
||||||
|
#ifndef __JV_WIN32_THREADS__
|
||||||
|
#define __JV_WIN32_THREADS__
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Typedefs.
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef HANDLE _Jv_ConditionVariable_t;
|
||||||
|
typedef HANDLE _Jv_Mutex_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int flags; // Flags are defined in implementation.
|
||||||
|
HANDLE handle; // Actual handle to the thread
|
||||||
|
} _Jv_Thread_t;
|
||||||
|
|
||||||
|
typedef void _Jv_ThreadStartFunc (java::lang::Thread *);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Condition variables.
|
||||||
|
//
|
||||||
|
|
||||||
|
inline void
|
||||||
|
_Jv_CondInit (_Jv_ConditionVariable_t *cv)
|
||||||
|
{
|
||||||
|
*cv = CreateEvent (NULL, 0, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define _Jv_HaveCondDestroy
|
||||||
|
|
||||||
|
inline void
|
||||||
|
_Jv_CondDestroy (_Jv_ConditionVariable_t *cv)
|
||||||
|
{
|
||||||
|
CloseHandle (*cv);
|
||||||
|
cv = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _Jv_CondWait (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu,
|
||||||
|
jlong millis, jint nanos);
|
||||||
|
|
||||||
|
inline int
|
||||||
|
_Jv_CondNotify (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *)
|
||||||
|
{
|
||||||
|
return PulseEvent (*cv) ? 0 : GetLastError (); // FIXME: Map error code?
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int
|
||||||
|
_Jv_CondNotifyAll (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *)
|
||||||
|
{
|
||||||
|
return PulseEvent (*cv) ? 0 : GetLastError (); // FIXME: Map error code?
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mutexes.
|
||||||
|
//
|
||||||
|
|
||||||
|
inline void
|
||||||
|
_Jv_MutexInit (_Jv_Mutex_t *mu)
|
||||||
|
{
|
||||||
|
*mu = CreateMutex (NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define _Jv_HaveMutexDestroy
|
||||||
|
|
||||||
|
inline void
|
||||||
|
_Jv_MutexDestroy (_Jv_Mutex_t *mu)
|
||||||
|
{
|
||||||
|
CloseHandle (*mu);
|
||||||
|
mu = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _Jv_MutexLock (_Jv_Mutex_t *mu);
|
||||||
|
|
||||||
|
inline int
|
||||||
|
_Jv_MutexUnlock (_Jv_Mutex_t *mu)
|
||||||
|
{
|
||||||
|
return ReleaseMutex(*mu) ? 0 : GetLastError(); // FIXME: Map error code?
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Thread creation and manipulation.
|
||||||
|
//
|
||||||
|
|
||||||
|
void _Jv_InitThreads (void);
|
||||||
|
void _Jv_ThreadInitData (_Jv_Thread_t **data, java::lang::Thread *thread);
|
||||||
|
|
||||||
|
inline java::lang::Thread *
|
||||||
|
_Jv_ThreadCurrent (void)
|
||||||
|
{
|
||||||
|
extern DWORD _Jv_ThreadKey;
|
||||||
|
return (java::lang::Thread *) TlsGetValue(_Jv_ThreadKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline _Jv_Thread_t *
|
||||||
|
_Jv_ThreadCurrentData (void)
|
||||||
|
{
|
||||||
|
extern DWORD _Jv_ThreadDataKey;
|
||||||
|
return (_Jv_Thread_t *) TlsGetValue(_Jv_ThreadDataKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
_Jv_ThreadYield (void)
|
||||||
|
{
|
||||||
|
Sleep (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _Jv_ThreadSetPriority (_Jv_Thread_t *data, jint prio);
|
||||||
|
void _Jv_ThreadStart (java::lang::Thread *thread, _Jv_Thread_t *data,
|
||||||
|
_Jv_ThreadStartFunc *meth);
|
||||||
|
void _Jv_ThreadWait (void);
|
||||||
|
void _Jv_ThreadInterrupt (_Jv_Thread_t *data);
|
||||||
|
|
||||||
|
// Remove defines from <windows.h> that conflict with various things in libgcj code
|
||||||
|
|
||||||
|
#undef TRUE
|
||||||
|
#undef FALSE
|
||||||
|
#undef MAX_PRIORITY
|
||||||
|
#undef MIN_PRIORITY
|
||||||
|
#undef min
|
||||||
|
#undef max
|
||||||
|
#undef interface
|
||||||
|
#undef STRICT
|
||||||
|
#undef VOID
|
||||||
|
|
||||||
|
#endif /* __JV_WIN32_THREADS__ */
|
250
libjava/java/io/natFileDescriptorWin32.cc
Normal file
250
libjava/java/io/natFileDescriptorWin32.cc
Normal file
|
@ -0,0 +1,250 @@
|
||||||
|
// natFileDescriptorWin32.cc - Native part of FileDescriptor class.
|
||||||
|
|
||||||
|
/* Copyright (C) 1998, 1999, 2000 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. */
|
||||||
|
|
||||||
|
// FIXME: In order to support interrupting of IO operations, we
|
||||||
|
// need to change to use the windows asynchronous IO functions
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <gcj/cni.h>
|
||||||
|
#include <jvm.h>
|
||||||
|
#include <java/io/FileDescriptor.h>
|
||||||
|
#include <java/io/SyncFailedException.h>
|
||||||
|
#include <java/io/IOException.h>
|
||||||
|
#include <java/io/InterruptedIOException.h>
|
||||||
|
#include <java/io/EOFException.h>
|
||||||
|
#include <java/lang/ArrayIndexOutOfBoundsException.h>
|
||||||
|
#include <java/lang/NullPointerException.h>
|
||||||
|
#include <java/lang/String.h>
|
||||||
|
#include <java/lang/Thread.h>
|
||||||
|
#include <java/io/FileNotFoundException.h>
|
||||||
|
|
||||||
|
static char *
|
||||||
|
winerr (void)
|
||||||
|
{
|
||||||
|
static LPVOID last = NULL;
|
||||||
|
LPVOID old = NULL;
|
||||||
|
|
||||||
|
if (last)
|
||||||
|
old = last;
|
||||||
|
|
||||||
|
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL,
|
||||||
|
GetLastError(),
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
(LPTSTR) &last,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (old)
|
||||||
|
LocalFree (old);
|
||||||
|
|
||||||
|
return (char *)last;
|
||||||
|
}
|
||||||
|
|
||||||
|
jboolean
|
||||||
|
java::io::FileDescriptor::valid (void) {
|
||||||
|
BY_HANDLE_FILE_INFORMATION info;
|
||||||
|
return GetFileInformationByHandle ((HANDLE)fd, &info) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
java::io::FileDescriptor::sync (void) {
|
||||||
|
if (! FlushFileBuffers ((HANDLE)fd))
|
||||||
|
JvThrow (new SyncFailedException (JvNewStringLatin1 (winerr ())));
|
||||||
|
}
|
||||||
|
|
||||||
|
jint
|
||||||
|
java::io::FileDescriptor::open (jstring path, jint jflags) {
|
||||||
|
|
||||||
|
HANDLE handle = NULL;
|
||||||
|
DWORD access = 0;
|
||||||
|
DWORD share = FILE_SHARE_READ;
|
||||||
|
DWORD create = OPEN_EXISTING;
|
||||||
|
char buf[MAX_PATH] = "";
|
||||||
|
|
||||||
|
jsize total = JvGetStringUTFRegion(path, 0, path->length(), buf);
|
||||||
|
buf[total] = '\0';
|
||||||
|
|
||||||
|
JvAssert((jflags & READ) || (jflags & WRITE));
|
||||||
|
|
||||||
|
if ((jflags & READ) && (jflags & WRITE))
|
||||||
|
{
|
||||||
|
access = GENERIC_READ | GENERIC_WRITE;
|
||||||
|
share = 0;
|
||||||
|
if (jflags & APPEND)
|
||||||
|
create = OPEN_ALWAYS;
|
||||||
|
else
|
||||||
|
create = CREATE_ALWAYS;
|
||||||
|
}
|
||||||
|
else if(jflags & READ)
|
||||||
|
access = GENERIC_READ;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
access = GENERIC_WRITE;
|
||||||
|
share = 0;
|
||||||
|
if (jflags & APPEND)
|
||||||
|
create = OPEN_ALWAYS;
|
||||||
|
else
|
||||||
|
create = CREATE_ALWAYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle = CreateFile(buf, access, share, NULL, create, 0, NULL);
|
||||||
|
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
char msg[MAX_PATH + 1000];
|
||||||
|
sprintf (msg, "%s: %s", buf, winerr ());
|
||||||
|
JvThrow (new FileNotFoundException (JvNewStringLatin1 (msg)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (jint)handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
java::io::FileDescriptor::write (jint b)
|
||||||
|
{
|
||||||
|
DWORD bytesWritten;
|
||||||
|
jbyte buf = (jbyte)b;
|
||||||
|
|
||||||
|
if (WriteFile ((HANDLE)fd, &buf, 1, &bytesWritten, NULL))
|
||||||
|
{
|
||||||
|
if (java::lang::Thread::interrupted())
|
||||||
|
{
|
||||||
|
InterruptedIOException *iioe = new InterruptedIOException (JvNewStringLatin1 ("write interrupted"));
|
||||||
|
iioe->bytesTransferred = bytesWritten;
|
||||||
|
JvThrow (iioe);
|
||||||
|
}
|
||||||
|
if (bytesWritten != 1)
|
||||||
|
JvThrow (new IOException (JvNewStringLatin1 (winerr ())));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
JvThrow (new IOException (JvNewStringLatin1 (winerr ())));
|
||||||
|
// FIXME: loop until bytesWritten == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
java::io::FileDescriptor::write(jbyteArray b, jint offset, jint len)
|
||||||
|
{
|
||||||
|
if (! b)
|
||||||
|
JvThrow (new java::lang::NullPointerException);
|
||||||
|
if(offset < 0 || len < 0 || offset + len > JvGetArrayLength (b))
|
||||||
|
JvThrow (new java::lang::ArrayIndexOutOfBoundsException);
|
||||||
|
|
||||||
|
jbyte *buf = elements (b) + offset;
|
||||||
|
DWORD bytesWritten;
|
||||||
|
if (WriteFile ((HANDLE)fd, buf, len, &bytesWritten, NULL))
|
||||||
|
{
|
||||||
|
if (java::lang::Thread::interrupted())
|
||||||
|
{
|
||||||
|
InterruptedIOException *iioe = new InterruptedIOException (JvNewStringLatin1 ("write interrupted"));
|
||||||
|
iioe->bytesTransferred = bytesWritten;
|
||||||
|
JvThrow (iioe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
JvThrow(new IOException (JvNewStringLatin1 (winerr ())));
|
||||||
|
// FIXME: loop until bytesWritten == len
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
java::io::FileDescriptor::close (void)
|
||||||
|
{
|
||||||
|
HANDLE save = (HANDLE)fd;
|
||||||
|
fd = (jint)INVALID_HANDLE_VALUE;
|
||||||
|
if (! CloseHandle (save))
|
||||||
|
JvThrow (new IOException (JvNewStringLatin1 (winerr ())));
|
||||||
|
}
|
||||||
|
|
||||||
|
jint
|
||||||
|
java::io::FileDescriptor::seek (jlong pos, jint whence)
|
||||||
|
{
|
||||||
|
JvAssert (whence == SET || whence == CUR);
|
||||||
|
|
||||||
|
jlong len = length();
|
||||||
|
jlong here = getFilePointer();
|
||||||
|
|
||||||
|
if ((whence == SET && pos > len) || (whence == CUR && here + pos > len))
|
||||||
|
JvThrow (new EOFException);
|
||||||
|
|
||||||
|
LONG high = pos >> 32;
|
||||||
|
DWORD low = SetFilePointer ((HANDLE)fd, (DWORD)(0xffffffff & pos), &high, whence == SET ? FILE_BEGIN : FILE_CURRENT);
|
||||||
|
if ((low == 0xffffffff) && (GetLastError () != NO_ERROR))
|
||||||
|
JvThrow (new IOException (JvNewStringLatin1 (winerr ())));
|
||||||
|
return low;
|
||||||
|
}
|
||||||
|
|
||||||
|
jlong
|
||||||
|
java::io::FileDescriptor::getFilePointer(void)
|
||||||
|
{
|
||||||
|
LONG high = 0;
|
||||||
|
DWORD low = SetFilePointer ((HANDLE)fd, 0, &high, FILE_CURRENT);
|
||||||
|
if ((low == 0xffffffff) && (GetLastError() != NO_ERROR))
|
||||||
|
JvThrow(new IOException (JvNewStringLatin1 (winerr ())));
|
||||||
|
return (((jlong)high) << 32L) | (jlong)low;
|
||||||
|
}
|
||||||
|
|
||||||
|
jlong
|
||||||
|
java::io::FileDescriptor::length(void)
|
||||||
|
{
|
||||||
|
DWORD high;
|
||||||
|
DWORD low;
|
||||||
|
|
||||||
|
low = GetFileSize ((HANDLE)fd, &high);
|
||||||
|
// FIXME: Error checking
|
||||||
|
return (((jlong)high) << 32L) | (jlong)low;
|
||||||
|
}
|
||||||
|
|
||||||
|
jint
|
||||||
|
java::io::FileDescriptor::read(void)
|
||||||
|
{
|
||||||
|
CHAR buf;
|
||||||
|
DWORD read;
|
||||||
|
|
||||||
|
if (! ReadFile ((HANDLE)fd, &buf, 1, &read, NULL))
|
||||||
|
JvThrow (new IOException (JvNewStringLatin1 (winerr ())));
|
||||||
|
if (! read)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return (jint)(buf & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
jint
|
||||||
|
java::io::FileDescriptor::read(jbyteArray buffer, jint offset, jint count)
|
||||||
|
{
|
||||||
|
if (! buffer)
|
||||||
|
JvThrow(new java::lang::NullPointerException);
|
||||||
|
|
||||||
|
jsize bsize = JvGetArrayLength (buffer);
|
||||||
|
if (offset < 0 || count < 0 || offset + count > bsize)
|
||||||
|
JvThrow (new java::lang::ArrayIndexOutOfBoundsException);
|
||||||
|
|
||||||
|
jbyte *bytes = elements (buffer) + offset;
|
||||||
|
|
||||||
|
DWORD read;
|
||||||
|
if (! ReadFile((HANDLE)fd, bytes, count, &read, NULL))
|
||||||
|
JvThrow (new IOException (JvNewStringLatin1 (winerr ())));
|
||||||
|
|
||||||
|
return (jint)read;
|
||||||
|
}
|
||||||
|
|
||||||
|
jint
|
||||||
|
java::io::FileDescriptor::available(void)
|
||||||
|
{
|
||||||
|
// FIXME:
|
||||||
|
return length() - getFilePointer();
|
||||||
|
}
|
210
libjava/java/io/natFileWin32.cc
Normal file
210
libjava/java/io/natFileWin32.cc
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|
// natFileWin32.cc - Native part of File class.
|
||||||
|
|
||||||
|
/* 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>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <gcj/cni.h>
|
||||||
|
#include <jvm.h>
|
||||||
|
#include <java/io/File.h>
|
||||||
|
#include <java/io/IOException.h>
|
||||||
|
#include <java/util/Vector.h>
|
||||||
|
#include <java/lang/String.h>
|
||||||
|
#include <java/io/FilenameFilter.h>
|
||||||
|
#include <java/lang/System.h>
|
||||||
|
|
||||||
|
jboolean
|
||||||
|
java::io::File::access (jstring canon, jint query)
|
||||||
|
{
|
||||||
|
if (! canon)
|
||||||
|
return false;
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
jsize total = JvGetStringUTFRegion (canon, 0, canon->length(), buf);
|
||||||
|
// FIXME?
|
||||||
|
buf[total] = '\0';
|
||||||
|
|
||||||
|
JvAssert (query == READ || query == WRITE || query == EXISTS);
|
||||||
|
|
||||||
|
// FIXME: Is it possible to differentiate between existing and reading?
|
||||||
|
// If the file exists but cannot be read because of the secuirty attributes
|
||||||
|
// on an NTFS disk this wont work (it reports it can be read but cant)
|
||||||
|
// Could we use something from the security API?
|
||||||
|
DWORD attributes = GetFileAttributes (buf);
|
||||||
|
if ((query == EXISTS) || (query == READ))
|
||||||
|
return (attributes == 0xffffffff) ? false : true;
|
||||||
|
else
|
||||||
|
return ((attributes != 0xffffffff) && ((attributes & FILE_ATTRIBUTE_READONLY) == 0)) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
jboolean
|
||||||
|
java::io::File::stat (jstring canon, jint query)
|
||||||
|
{
|
||||||
|
if (! canon)
|
||||||
|
return false;
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
jsize total = JvGetStringUTFRegion (canon, 0, canon->length(), buf);
|
||||||
|
// FIXME?
|
||||||
|
buf[total] = '\0';
|
||||||
|
|
||||||
|
JvAssert (query == DIRECTORY || query == ISFILE);
|
||||||
|
|
||||||
|
DWORD attributes = GetFileAttributes (buf);
|
||||||
|
if (attributes == 0xffffffff)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (query == DIRECTORY)
|
||||||
|
return attributes & FILE_ATTRIBUTE_DIRECTORY ? true : false;
|
||||||
|
else
|
||||||
|
return attributes & FILE_ATTRIBUTE_DIRECTORY ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
jlong
|
||||||
|
java::io::File::attr (jstring canon, jint query)
|
||||||
|
{
|
||||||
|
if (! canon)
|
||||||
|
return false;
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
jsize total = JvGetStringUTFRegion (canon, 0, canon->length(), buf);
|
||||||
|
// FIXME?
|
||||||
|
buf[total] = '\0';
|
||||||
|
|
||||||
|
JvAssert (query == MODIFIED || query == LENGTH);
|
||||||
|
|
||||||
|
WIN32_FILE_ATTRIBUTE_DATA info;
|
||||||
|
if (! GetFileAttributesEx(buf, GetFileExInfoStandard, &info))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (query == LENGTH)
|
||||||
|
return ((long long)info.nFileSizeHigh) << 32 | (unsigned long long)info.nFileSizeLow;
|
||||||
|
else {
|
||||||
|
// FIXME? This is somewhat compiler dependant (the LL constant suffix)
|
||||||
|
// The file time as return by windows is the number of 100-nanosecond intervals since January 1, 1601
|
||||||
|
return (((((long long)info.ftLastWriteTime.dwHighDateTime) << 32) | ((unsigned long long)info.ftLastWriteTime.dwLowDateTime)) - 116444736000000000LL) / 10000LL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jstring
|
||||||
|
java::io::File::getCanonicalPath (void)
|
||||||
|
{
|
||||||
|
char buf[MAX_PATH], buf2[MAX_PATH];
|
||||||
|
jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
|
||||||
|
// FIXME?
|
||||||
|
buf[total] = '\0';
|
||||||
|
|
||||||
|
LPTSTR unused;
|
||||||
|
if(!GetFullPathName(buf, MAX_PATH, buf2, &unused))
|
||||||
|
_Jv_Throw (new IOException (JvNewStringLatin1 ("GetFullPathName failed")));
|
||||||
|
|
||||||
|
// FIXME: what encoding to assume for file names? This affects many
|
||||||
|
// calls.
|
||||||
|
return JvNewStringUTF(buf2);
|
||||||
|
}
|
||||||
|
|
||||||
|
jboolean
|
||||||
|
java::io::File::isAbsolute (void)
|
||||||
|
{
|
||||||
|
if (path->charAt(0) == '/' || path->charAt(0) == '\\')
|
||||||
|
return true;
|
||||||
|
if (path->length() < 3)
|
||||||
|
return false;
|
||||||
|
// Hard-code A-Za-z because Windows (I think) can't use non-ASCII
|
||||||
|
// letters as drive names.
|
||||||
|
if ((path->charAt(0) < 'a' || path->charAt(0) > 'z')
|
||||||
|
&& (path->charAt(0) < 'A' || path->charAt(0) > 'Z'))
|
||||||
|
return false;
|
||||||
|
return (path->charAt(1) == ':'
|
||||||
|
&& (path->charAt(2) == '/' || path->charAt(2) == '\\'));
|
||||||
|
}
|
||||||
|
|
||||||
|
jstringArray
|
||||||
|
java::io::File::performList (jstring canon, FilenameFilter *filter)
|
||||||
|
{
|
||||||
|
if (! canon)
|
||||||
|
return NULL;
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
jsize total = JvGetStringUTFRegion (canon, 0, canon->length(), buf);
|
||||||
|
// FIXME?
|
||||||
|
strcpy(&buf[total], "\\*.*");
|
||||||
|
|
||||||
|
WIN32_FIND_DATA data;
|
||||||
|
HANDLE handle = FindFirstFile (buf, &data);
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
java::util::Vector *vec = new java::util::Vector ();
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (strcmp (data.cFileName, ".") && strcmp (data.cFileName, ".."))
|
||||||
|
{
|
||||||
|
jstring name = JvNewStringUTF (data.cFileName);
|
||||||
|
if (! filter || (filter && filter->accept(this, name)))
|
||||||
|
vec->addElement (name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (FindNextFile (handle, &data));
|
||||||
|
|
||||||
|
if (GetLastError () != ERROR_NO_MORE_FILES)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
FindClose (handle);
|
||||||
|
|
||||||
|
jobjectArray ret = JvNewObjectArray (vec->size(), canon->getClass(), NULL);
|
||||||
|
vec->copyInto (ret);
|
||||||
|
return reinterpret_cast<jstringArray> (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
jboolean
|
||||||
|
java::io::File::performMkdir (void)
|
||||||
|
{
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
jsize total = JvGetStringUTFRegion(path, 0, path->length(), buf);
|
||||||
|
// FIXME?
|
||||||
|
buf[total] = '\0';
|
||||||
|
|
||||||
|
return (CreateDirectory(buf, NULL)) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
jboolean
|
||||||
|
java::io::File::performRenameTo (File *dest)
|
||||||
|
{
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
jsize total = JvGetStringUTFRegion(path, 0, path->length(), buf);
|
||||||
|
// FIXME?
|
||||||
|
buf[total] = '\0';
|
||||||
|
char buf2[MAX_PATH];
|
||||||
|
total = JvGetStringUTFRegion(dest->path, 0, dest->path->length(), buf2);
|
||||||
|
// FIXME?
|
||||||
|
buf2[total] = '\0';
|
||||||
|
|
||||||
|
return (MoveFile(buf, buf2)) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
jboolean
|
||||||
|
java::io::File::performDelete (jstring canon)
|
||||||
|
{
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
jsize total = JvGetStringUTFRegion(canon, 0, canon->length(), buf);
|
||||||
|
// FIXME?
|
||||||
|
buf[total] = '\0';
|
||||||
|
|
||||||
|
DWORD attributes = GetFileAttributes (buf);
|
||||||
|
if (attributes == 0xffffffff)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (attributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
|
return (RemoveDirectory (buf)) ? true : false;
|
||||||
|
else
|
||||||
|
return (DeleteFile (buf)) ? true : false;
|
||||||
|
}
|
|
@ -14,6 +14,17 @@ details. */
|
||||||
# define _REENTRANT 1
|
# define _REENTRANT 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_WINSOCK
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winsock.h>
|
||||||
|
|
||||||
|
#ifndef MAXHOSTNAMELEN
|
||||||
|
#define MAXHOSTNAMELEN 64
|
||||||
|
#endif /* MAXHOSTNAMELEN */
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -35,6 +46,8 @@ details. */
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* USE_WINSOCK */
|
||||||
|
|
||||||
#include <gcj/cni.h>
|
#include <gcj/cni.h>
|
||||||
#include <jvm.h>
|
#include <jvm.h>
|
||||||
#include <java/net/InetAddress.h>
|
#include <java/net/InetAddress.h>
|
||||||
|
|
|
@ -8,6 +8,15 @@ details. */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#ifdef USE_WINSOCK
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winsock.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#ifndef ENOPROTOOPT
|
||||||
|
#define ENOPROTOOPT 109
|
||||||
|
#endif
|
||||||
|
#else /* USE_WINSOCK */
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,6 +35,7 @@ details. */
|
||||||
#endif
|
#endif
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#endif /* USE_WINSOCK */
|
||||||
|
|
||||||
#if HAVE_BSTRING_H
|
#if HAVE_BSTRING_H
|
||||||
// Needed for bzero, implicitly used by FD_ZERO on IRIX 5.2
|
// Needed for bzero, implicitly used by FD_ZERO on IRIX 5.2
|
||||||
|
|
|
@ -8,7 +8,17 @@ details. */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
|
||||||
#ifndef DISABLE_JAVA_NET
|
#ifndef DISABLE_JAVA_NET
|
||||||
|
#ifdef USE_WINSOCK
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winsock.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#ifndef ENOPROTOOPT
|
||||||
|
#define ENOPROTOOPT 109
|
||||||
|
#endif
|
||||||
|
#else /* USE_WINSOCK */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
@ -19,6 +29,7 @@ details. */
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#endif /* USE_WINSOCK */
|
||||||
#endif /* DISABLE_JAVA_NET */
|
#endif /* DISABLE_JAVA_NET */
|
||||||
|
|
||||||
#if HAVE_BSTRING_H
|
#if HAVE_BSTRING_H
|
||||||
|
|
|
@ -10,6 +10,15 @@ details. */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#ifdef USE_WIN32_SIGNALLING
|
||||||
|
#include <windows.h>
|
||||||
|
#endif /* USE_WIN32_SIGNALLING */
|
||||||
|
|
||||||
|
#ifdef USE_WINSOCK
|
||||||
|
#undef __INSIDE_CYGWIN__
|
||||||
|
#include <winsock.h>
|
||||||
|
#endif /* USE_WINSOCK */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -589,6 +598,32 @@ _Jv_ThisExecutable (const char *name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_WIN32_SIGNALLING
|
||||||
|
|
||||||
|
extern "C" int* win32_get_restart_frame (void *);
|
||||||
|
|
||||||
|
LONG CALLBACK
|
||||||
|
win32_exception_handler (LPEXCEPTION_POINTERS e)
|
||||||
|
{
|
||||||
|
int* setjmp_buf;
|
||||||
|
if (e->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
|
||||||
|
setjmp_buf = win32_get_restart_frame (nullp);
|
||||||
|
else if (e->ExceptionRecord->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO)
|
||||||
|
setjmp_buf = win32_get_restart_frame (arithexception);
|
||||||
|
else
|
||||||
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
|
|
||||||
|
e->ContextRecord->Ebp = setjmp_buf[0];
|
||||||
|
// FIXME: Why does i386-signal.h increment the PC here, do we need to do it?
|
||||||
|
e->ContextRecord->Eip = setjmp_buf[1];
|
||||||
|
// FIXME: Is this the stack pointer? Do we need it?
|
||||||
|
e->ContextRecord->Esp = setjmp_buf[2];
|
||||||
|
|
||||||
|
return EXCEPTION_CONTINUE_EXECUTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
main_init ()
|
main_init ()
|
||||||
{
|
{
|
||||||
|
@ -606,12 +641,24 @@ main_init ()
|
||||||
LTDL_SET_PRELOADED_SYMBOLS ();
|
LTDL_SET_PRELOADED_SYMBOLS ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FIXME: we only want this on POSIX systems.
|
#ifdef USE_WINSOCK
|
||||||
|
// Initialise winsock for networking
|
||||||
|
WSADATA data;
|
||||||
|
if (WSAStartup (MAKEWORD (1, 1), &data))
|
||||||
|
MessageBox (NULL, "Error initialising winsock library.", "Error", MB_OK | MB_ICONEXCLAMATION);
|
||||||
|
#endif /* USE_WINSOCK */
|
||||||
|
|
||||||
|
#ifdef USE_WIN32_SIGNALLING
|
||||||
|
// Install exception handler
|
||||||
|
SetUnhandledExceptionFilter (win32_exception_handler);
|
||||||
|
#else
|
||||||
|
// We only want this on POSIX systems.
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
act.sa_handler = SIG_IGN;
|
act.sa_handler = SIG_IGN;
|
||||||
sigemptyset (&act.sa_mask);
|
sigemptyset (&act.sa_mask);
|
||||||
act.sa_flags = 0;
|
act.sa_flags = 0;
|
||||||
sigaction (SIGPIPE, &act, NULL);
|
sigaction (SIGPIPE, &act, NULL);
|
||||||
|
#endif /* USE_WIN32_SIGNALLING */
|
||||||
|
|
||||||
_Jv_JNI_Init ();
|
_Jv_JNI_Init ();
|
||||||
}
|
}
|
||||||
|
|
247
libjava/win32-threads.cc
Normal file
247
libjava/win32-threads.cc
Normal file
|
@ -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:
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue