mirror of
https://github.com/corda/corda.git
synced 2025-01-19 03:06:36 +00:00
mork work on the windows port
This commit is contained in:
parent
cb7189c5a7
commit
1381267e70
@ -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
|
||||
|
@ -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 };
|
||||
|
26
makefile
26
makefile
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user