mork work on the windows port

This commit is contained in:
Joel Dice 2007-10-23 11:22:48 -06:00
parent cb7189c5a7
commit 1381267e70
4 changed files with 128 additions and 66 deletions

View File

@ -5,9 +5,14 @@
#include "time.h"
#include "string.h"
#include "stdio.h"
#include "stdint.h"
#include "jni.h"
#include "jni-util.h"
#ifdef WIN32
# include "windows.h"
#endif
#ifdef __APPLE__
# define SO_SUFFIX ".jnilib"
#else
@ -41,14 +46,15 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jint code)
case JavaIoTmpdir:
return e->NewStringUTF("/tmp");
case UserHome:
return e->NewStringUTF("/home/scharff");
case UserHome: {
#ifdef WIN32
LPWSTR home = _wgetenv(L"USERPROFILE");
return JvNewString(reinterpret_cast<jchar*>(home), lstrlenW(home));
return e->NewString(reinterpret_cast<jchar*>(home), lstrlenW(home));
#else
return e->NewStringUTF(getenv("HOME"));
#endif
}
default:
throwNew(e, "java/lang/RuntimeException", 0);
return 0;
@ -58,10 +64,31 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jint code)
extern "C" JNIEXPORT jlong JNICALL
Java_java_lang_System_currentTimeMillis(JNIEnv*, jclass)
{
#ifdef WIN32
static LARGE_INTEGER frequency;
static LARGE_INTEGER time;
static bool init = true;
if (init) {
QueryPerformanceFrequency(&frequency);
if (frequency.QuadPart == 0) {
return 0;
}
init = false;
}
QueryPerformanceCounter(&time);
return static_cast<int64_t>
(((static_cast<double>(time.QuadPart)) * 1000.0) /
(static_cast<double>(frequency.QuadPart)));
#else
timeval tv = { 0, 0 };
gettimeofday(&tv, 0);
return (static_cast<jlong>(tv.tv_sec) * 1000) +
(static_cast<jlong>(tv.tv_usec) / 1000);
#endif
}
extern "C" JNIEXPORT jstring JNICALL

View File

@ -6,6 +6,7 @@
#ifdef WIN32
# include <winsock2.h>
# include <errno.h>
#else
# include <fcntl.h>
# include <errno.h>
@ -23,31 +24,60 @@
#define java_nio_channels_SelectionKey_OP_WRITE 4L
#define java_nio_channels_SelectionKey_OP_ACCEPT 16L
#ifdef WIN32
typedef int socklen_t;
#endif
inline void* operator new(size_t, void* p) throw() { return p; }
namespace {
inline const char*
errorString(int e)
inline jbyteArray
charsToArray(JNIEnv* e, const char* s)
{
return strerror(e);
unsigned length = strlen(s);
jbyteArray a = e->NewByteArray(length + 1);
e->SetByteArrayRegion(a, 0, length + 1, reinterpret_cast<const jbyte*>(s));
return a;
}
inline const char*
errorString()
inline jbyteArray
errorString(JNIEnv* e, int n)
{
return charsToArray(e, strerror(n));
}
inline jbyteArray
errorString(JNIEnv* e)
{
#ifdef WIN32
const unsigned size = 64;
char buffer[size];
snprintf(buffer, size, "wsa code: %d", WSAGetLastError());
return JvNewStringLatin1(buffer);
return charsToArray(e, buffer);
#else
return errorString(errno);
#endif
}
void
throwIOException(JNIEnv* e, const char* s)
{
throwNew(e, "java/io/IOException", s);
}
void
throwIOException(JNIEnv* e, jbyteArray a)
{
jbyte* s = static_cast<jbyte*>(e->GetPrimitiveArrayCritical(a, 0));
throwIOException(e, reinterpret_cast<const char*>(s));
e->ReleasePrimitiveArrayCritical(a, s, 0);
}
void
throwIOException(JNIEnv* e)
{
throwNew(e, "java/io/IOException", errorString());
throwIOException(e, errorString(e));
}
void
@ -97,15 +127,18 @@ makeNonblocking(JNIEnv* e, int d)
#ifdef WIN32
u_long a = 1;
int r = ioctlsocket(d, FIONBIO, &a);
if (r != 0) throw new IOException(errorString());
if (r != 0) {
throwIOException(e);
return false;
}
#else
int r = fcntl(d, F_SETFL, fcntl(d, F_GETFL) | O_NONBLOCK);
if (r < 0) {
throwIOException(e);
return false;
}
return true;
#endif
return true;
}
void
@ -153,9 +186,6 @@ doAccept(JNIEnv* e, int s)
socklen_t length = sizeof(address);
int r = ::accept(s, &address, &length);
if (r >= 0) {
// System::out->print(JvNewStringLatin1("doAccept: socket: "));
// System::out->println(String::valueOf((jint) r));
makeNonblocking(e, r);
return r;
} else {
@ -193,7 +223,7 @@ makeSocket(JNIEnv* e, bool blocking = false)
WSADATA data;
int r = WSAStartup(MAKEWORD(2, 2), &data);
if (r or LOBYTE(data.wVersion) != 2 or HIBYTE(data.wVersion) != 2) {
throw new IOException(JvNewStringLatin1("WSAStartup failed"));
throwIOException(e, "WSAStartup failed");
}
}
#endif
@ -201,9 +231,6 @@ makeSocket(JNIEnv* e, bool blocking = false)
int s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s < 0) { throwIOException(e); return s; }
// System::out->print(JvNewStringLatin1("makeSocket: socket: "));
// System::out->println(String::valueOf((jint) s));
if (not blocking) makeNonblocking(e, s);
return s;
@ -261,8 +288,8 @@ Java_java_nio_channels_SocketChannel_natRead(JNIEnv *e,
jint length)
{
jboolean isCopy;
uint8_t *buf =
reinterpret_cast<uint8_t*>(e->GetPrimitiveArrayCritical(buffer, &isCopy));
uint8_t *buf = static_cast<uint8_t*>
(e->GetPrimitiveArrayCritical(buffer, &isCopy));
int r = ::doRead(socket, buf + offset, length);
e->ReleasePrimitiveArrayCritical(buffer, buf, 0);
if (r < 0) {
@ -286,8 +313,8 @@ Java_java_nio_channels_SocketChannel_natWrite(JNIEnv *e,
jint length)
{
jboolean isCopy;
uint8_t *buf =
reinterpret_cast<uint8_t*>(e->GetPrimitiveArrayCritical(buffer, &isCopy));
uint8_t *buf = static_cast<uint8_t*>
(e->GetPrimitiveArrayCritical(buffer, &isCopy));
int r = ::doWrite(socket, buf + offset, length);
e->ReleasePrimitiveArrayCritical(buffer, buf, 0);
if (r < 0) {
@ -311,7 +338,7 @@ Java_java_nio_channels_SocketChannel_natThrowWriteError(JNIEnv *e,
int r = getsockopt(socket, SOL_SOCKET, SO_ERROR,
reinterpret_cast<char*>(&error), &size);
if (r != 0 or size != sizeof(int) or error != 0) {
throwNew(e, "java/io/IOException", errorString(error));
throwIOException(e, errorString(e, error));
}
}
@ -332,26 +359,26 @@ class Pipe {
// pipe descriptors or others. Thus, to implement
// Selector.wakeup(), we make a socket connection via the loopback
// interface and use it as a pipe.
Pipe(): connected_(false), listener_(-1), reader_(-1), writer_(-1) {
Pipe(JNIEnv* e): connected_(false), listener_(-1), reader_(-1), writer_(-1) {
sockaddr_in address;
address.sin_family = AF_INET;
address.sin_port = 0;
address.sin_addr.s_addr = inet_addr("127.0.0.1"); //INADDR_LOOPBACK;
listener_ = makeSocket();
::doListen(listener_, &address);
listener_ = makeSocket(e, false);
::doListen(e, listener_, &address);
socklen_t length = sizeof(sockaddr_in);
int r = getsockname(listener_, reinterpret_cast<sockaddr*>(&address),
&length);
if (r) {
throw new IOException(errorString());
throwIOException(e);
}
writer_ = makeSocket(true);
connected_ = ::doConnect(writer_, &address);
writer_ = makeSocket(e, true);
connected_ = ::doConnect(e, writer_, &address);
}
~Pipe() {
void dispose() {
if (listener_ >= 0) ::close(listener_);
if (reader_ >= 0) ::close(reader_);
if (writer_ >= 0) ::close(writer_);
@ -434,8 +461,6 @@ struct SelectorState {
} // namespace
inline void* operator new(size_t, void* p) throw() { return p; }
extern "C" JNIEXPORT jlong JNICALL
Java_java_nio_channels_SocketSelector_natInit(JNIEnv* e, jclass)
{
@ -494,9 +519,9 @@ Java_java_nio_channels_SocketSelector_natSelectClearAll(JNIEnv *, jclass,
jlong state)
{
SelectorState* s = reinterpret_cast<SelectorState*>(state);
FD_CLR(socket, &(s->read));
FD_CLR(socket, &(s->write));
FD_CLR(socket, &(s->except));
FD_CLR(static_cast<unsigned>(socket), &(s->read));
FD_CLR(static_cast<unsigned>(socket), &(s->write));
FD_CLR(static_cast<unsigned>(socket), &(s->except));
}
extern "C" JNIEXPORT jint JNICALL
@ -510,17 +535,17 @@ Java_java_nio_channels_SocketSelector_natSelectUpdateInterestSet(JNIEnv *,
SelectorState* s = reinterpret_cast<SelectorState*>(state);
if (interest & (java_nio_channels_SelectionKey_OP_READ |
java_nio_channels_SelectionKey_OP_ACCEPT)) {
FD_SET(socket, &(s->read));
FD_SET(static_cast<unsigned>(socket), &(s->read));
if (max < socket) max = socket;
} else {
FD_CLR(socket, &(s->read));
FD_CLR(static_cast<unsigned>(socket), &(s->read));
}
if (interest & java_nio_channels_SelectionKey_OP_WRITE) {
FD_SET(socket, &(s->write));
FD_SET(static_cast<unsigned>(socket), &(s->write));
if (max < socket) max = socket;
} else {
FD_CLR(socket, &(s->write));
FD_CLR(static_cast<unsigned>(socket), &(s->write));
}
return max;
}
@ -534,7 +559,7 @@ Java_java_nio_channels_SocketSelector_natDoSocketSelect(JNIEnv *e, jclass,
SelectorState* s = reinterpret_cast<SelectorState*>(state);
if (s->control.reader() >= 0) {
int socket = s->control.reader();
FD_SET(socket, &(s->read));
FD_SET(static_cast<unsigned>(socket), &(s->read));
if (max < socket) max = socket;
}
timeval time = { interval / 1000, (interval % 1000) * 1000 };

View File

@ -1,4 +1,4 @@
MAKEFLAGS = -s
#MAKEFLAGS = -s
input = $(cls)/Memory.class
@ -12,6 +12,10 @@ endif
build-platform = $(shell uname -s | tr [:upper:] [:lower:])
ifeq ($(build-platform),cygwin_nt-5.1)
build-platform = windows
endif
arch = $(build-arch)
platform = $(build-platform)
@ -49,7 +53,8 @@ warnings = -Wall -Wextra -Werror -Wunused-parameter \
-Winit-self -Wconversion
cflags = $(warnings) -fPIC -fno-rtti -fno-exceptions -fvisibility=hidden \
-I$(src) -I$(build-dir) $(thread-cflags) -D__STDC_LIMIT_MACROS
-I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux -I$(src) -I$(build-dir) \
$(thread-cflags) -D__STDC_LIMIT_MACROS
lflags = -lpthread -ldl -lm -lz
@ -73,9 +78,10 @@ ifeq ($(platform),windows)
rdynamic =
so-extension = dll
thread-cflags =
lflags = -L$(lib) -lm -lz -Wl,--kill-at
cflags = $(warnings) -fno-rtti -fno-exceptions -I$(src) -I$(build-dir) \
$(thread-cflags) -D__STDC_LIMIT_MACROS -I$(inc)
lflags = -L$(lib) -lm -lz -lws2_32 -Wl,--kill-at
cflags = $(warnings) -fno-rtti -fno-exceptions -I$(build-dir) \
$(thread-cflags) -D__STDC_LIMIT_MACROS -I$(JAVA_HOME)/include -I$(inc) \
-idirafter $(src)
endif
ifeq ($(mode),debug)
@ -105,7 +111,7 @@ java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(cls)/%.class,$(x)))
jni-sources = $(shell find $(classpath) -name '*.cpp')
jni-objects = $(call cpp-objects,$(jni-sources),$(classpath),$(bld))
jni-cflags = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux $(cflags)
jni-cflags = $(cflags)
jni-library = $(bld)/libnatives.$(so-extension)
generated-code = \
@ -219,7 +225,7 @@ $(build-dir)/type-generator.o: \
define compile-class
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
@mkdir -p -m 1777 $(dir $(@))
$(javac) -bootclasspath $(classpath) -classpath $(classpath) \
-d $(cls) $(<)
@touch $(@)
@ -233,7 +239,7 @@ $(cls)/%.class: $(test)/%.java
define compile-object
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
@mkdir -p -m 1777 $(dir $(@))
$(cxx) $(cflags) -c $(<) -o $(@)
endef
@ -245,12 +251,12 @@ $(interpreter-asm-objects): $(bld)/%-asm.o: $(src)/%.S
$(generator-objects): $(build-dir)/%.o: $(src)/%.cpp
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
@mkdir -p -m 1777 $(dir $(@))
$(build-cxx) $(cflags) -c $(<) -o $(@)
$(jni-objects): $(bld)/%.o: $(classpath)/%.cpp
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
@mkdir -p -m 1777 $(dir $(@))
$(cxx) $(jni-cflags) -c $(<) -o $(@)
$(jni-library): $(jni-objects)

View File

@ -21,8 +21,8 @@ class MutexResource {
}
~MutexResource() {
int r UNUSED = ReleaseMutex(m);
assert(s, r == 0);
bool success UNUSED = ReleaseMutex(m);
assert(s, success);
}
private:
@ -137,8 +137,8 @@ class MySystem: public System {
if (owner_ == t) {
if (-- depth == 0) {
owner_ = 0;
int r UNUSED = ReleaseMutex(mutex);
assert(s, r == 0);
bool success UNUSED = ReleaseMutex(mutex);
assert(s, success);
}
} else {
sysAbort(s);
@ -186,16 +186,16 @@ class MySystem: public System {
this->depth = 0;
owner_ = 0;
int r UNUSED = ReleaseMutex(mutex);
assert(s, r == 0);
bool success UNUSED = ReleaseMutex(mutex);
assert(s, success);
r = ResetEvent(t->event);
assert(s, r);
success = ResetEvent(t->event);
assert(s, success);
r = ReleaseMutex(t->mutex);
assert(s, r == 0);
success = ReleaseMutex(t->mutex);
assert(s, success);
r = WaitForSingleObject(t->event, (time ? time : INFINITE));
int r UNUSED = WaitForSingleObject(t->event, (time ? time : INFINITE));
assert(s, r == WAIT_OBJECT_0);
r = WaitForSingleObject(t->mutex, INFINITE);
@ -287,7 +287,7 @@ class MySystem: public System {
public:
Local(System* s): s(s) {
key = TlsAlloc();
assert(s, key == TLS_OUT_OF_INDEXES);
assert(s, key != TLS_OUT_OF_INDEXES);
}
virtual void* get() {
@ -380,7 +380,9 @@ class MySystem: public System {
fprintf(stderr, "close %p\n", handle);
}
FreeLibrary(handle);
if (name_) {
FreeLibrary(handle);
}
if (next_) {
next_->dispose();
@ -545,8 +547,10 @@ class MySystem: public System {
char buffer[size];
snprintf(buffer, size, "%s" SO_SUFFIX, name);
handle = LoadLibrary(buffer);
} else {
} else if (name) {
handle = LoadLibrary(name);
} else {
handle = GetModuleHandle(0);
}
if (handle) {
@ -566,7 +570,6 @@ class MySystem: public System {
Library(this, handle, n, mapName, next);
return 0;
} else {
// fprintf(stderr, "dlerror: %s\n", dlerror());
return 1;
}
}
@ -598,6 +601,7 @@ class MySystem: public System {
}
virtual void abort() {
asm("int3");
::abort();
}