From 0aacee389fdb553ef9925d0135eefcb501a67726 Mon Sep 17 00:00:00 2001 From: Martin Hurton Date: Mon, 31 Aug 2009 11:31:32 +0200 Subject: POSIX threads don't use errno to report errors Fix simple_semaphore to follow POSIX threads convention for reporting errors. --- src/err.hpp | 9 +++++---- src/simple_semaphore.hpp | 12 ++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/err.hpp b/src/err.hpp index 3854d8a..c1b2916 100644 --- a/src/err.hpp +++ b/src/err.hpp @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -81,10 +82,10 @@ namespace zmq }} while (false) // Provides convenient way to check for POSIX errors. -#define posix_assert(x) do {\ -fprintf (stderr, "%s (%s:%d)\n", strerror (x), __FILE__, __LINE__);\ -abort ();\ -} while (false) +#define posix_assert(x) do { if ((x)) {\ + fprintf (stderr, "%s (%s:%d)\n", strerror (x), __FILE__, __LINE__);\ + abort ();\ +}} while (false) // Provides convenient way to check for errors from getaddrinfo. #define gai_assert(x) do { if (x) {\ diff --git a/src/simple_semaphore.hpp b/src/simple_semaphore.hpp index b48a7f5..209ccb4 100644 --- a/src/simple_semaphore.hpp +++ b/src/simple_semaphore.hpp @@ -53,32 +53,32 @@ namespace zmq inline simple_semaphore_t () { int rc = pthread_mutex_init (&mutex, NULL); - errno_assert (rc == 0); + posix_assert (rc); rc = pthread_mutex_lock (&mutex); - errno_assert (rc == 0); + posix_assert (rc); } // Destroy the semaphore. inline ~simple_semaphore_t () { int rc = pthread_mutex_unlock (&mutex); - errno_assert (rc == 0); + posix_assert (rc); rc = pthread_mutex_destroy (&mutex); - errno_assert (rc == 0); + posix_assert (rc); } // Wait for the semaphore. inline void wait () { int rc = pthread_mutex_lock (&mutex); - errno_assert (rc == 0); + posix_assert (rc); } // Post the semaphore. inline void post () { int rc = pthread_mutex_unlock (&mutex); - errno_assert (rc == 0); + posix_assert (rc); } private: -- cgit v1.2.3 From 1f06d99a0f563fdc32e9c00392f9875ba3009593 Mon Sep 17 00:00:00 2001 From: Martin Hurton Date: Mon, 31 Aug 2009 13:11:46 +0200 Subject: Add Java binding --- Makefile.am | 8 +- configure.in | 54 ++++++++- java/Context.cpp | 92 ++++++++++++++++ java/Makefile.am | 72 ++++++++++++ java/Message.cpp | 138 +++++++++++++++++++++++ java/Socket.cpp | 276 ++++++++++++++++++++++++++++++++++++++++++++++ java/org/zmq/Context.java | 47 ++++++++ java/org/zmq/Message.java | 66 +++++++++++ java/org/zmq/Socket.java | 141 +++++++++++++++++++++++ 9 files changed, 891 insertions(+), 3 deletions(-) create mode 100644 java/Context.cpp create mode 100644 java/Makefile.am create mode 100644 java/Message.cpp create mode 100644 java/Socket.cpp create mode 100644 java/org/zmq/Context.java create mode 100644 java/org/zmq/Message.java create mode 100644 java/org/zmq/Socket.java diff --git a/Makefile.am b/Makefile.am index 15424ff..3055e64 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,5 +8,9 @@ if BUILD_RUBY DIR_R = ruby endif -SUBDIRS = src perf $(DIR_P) $(DIR_R) -DIST_SUBDIRS = src perf $(DIR_P) $(DIR_R) +if BUILD_JAVA +DIR_J = java +endif + +SUBDIRS = src perf $(DIR_P) $(DIR_R) $(DIR_J) +DIST_SUBDIRS = src perf $(DIR_P) $(DIR_R) $(DIR_J) diff --git a/configure.in b/configure.in index d4e60c5..0cd28a5 100644 --- a/configure.in +++ b/configure.in @@ -259,7 +259,58 @@ if test "x$pyzmq" != "xyes"; then [python third-party/openpgm/libpgm-1.0.0/openpgm/pgm/version_generator.py > \ third-party/openpgm/libpgm-1.0.0/openpgm/pgm/version.c]) +# Java language binding +jzmq="no" +AC_ARG_WITH([java], [AS_HELP_STRING([--with-java], [build Java language binding [default=no]])], [with_java=yes], [with_java=no]) +if test "x$with_java" != "xno"; then + AC_PATH_PROG(JAVAC, javac, "no",[$PATH:$JAVA_HOME/bin]) + if test "x$JAVAC" = "xno"; then + AC_MSG_ERROR([To run configure with --with-java option, javac has to be on the path.]); + fi + + AC_PATH_PROG(JAVAH, javah, "no",[$PATH:$JAVA_HOME/bin]) + if test "x$JAVAH" = "xno"; then + AC_MSG_ERROR([To run configure with --with-java option, javah has to be on the path.]); + fi + + AC_PATH_PROG(JAR, jar, "no", [$PATH:$JAVA_HOME/bin]) + if test "x$JAR" = "xno"; then + AC_MSG_ERROR([To run configure with --with-java option, jar has to be on the path.]); + fi + + if test "x$JAVA_HOME" = "x"; then + AC_MSG_ERROR([To run configure with --with-java, please set the JAVA_HOME variable to your JDK environment.]); + fi + + AC_MSG_CHECKING([for jni.h in a $JAVA_HOME/include dir]) + if test -f $JAVA_HOME/include/jni.h; then + AC_MSG_RESULT([yes]) + else + AC_MSG_ERROR([Could not find jni.h in $JAVA_HOME/include directory.]); + fi + + JAVAROOT=./ + AC_SUBST(JAVAROOT) + + case "${host_os}" in + *solaris*) + JAVA_INCLUDE="-I.. -I${JAVA_HOME}/include -I ${JAVA_HOME}/include/solaris" + ;; + *openbsd*) + JAVA_INCLUDE="-I.. -I${JAVA_HOME}/include -I ${JAVA_HOME}/include/openbsd" + ;; + *) + JAVA_INCLUDE="-I.. -I${JAVA_HOME}/include -I ${JAVA_HOME}/include/linux" + ;; + esac + + AC_SUBST(JAVA_INCLUDE) + + jzmq="yes" +fi + AM_CONDITIONAL(BUILD_PYTHON, test "x$pyzmq" = "xyes") +AM_CONDITIONAL(BUILD_JAVA, test "x$jzmq" = "xyes") AC_SUBST(stdint) AC_SUBST(inttypes) @@ -276,7 +327,7 @@ AC_TYPE_SIGNAL AC_CHECK_FUNCS(perror gettimeofday memset socket getifaddrs freeifaddrs) AC_OUTPUT(Makefile src/Makefile python/Makefile python/setup.py ruby/Makefile \ - perf/Makefile perf/c/Makefile perf/cpp/Makefile) + java/Makefile perf/Makefile perf/c/Makefile perf/cpp/Makefile) AC_MSG_RESULT([]) AC_MSG_RESULT([ ******************************************************** ]) @@ -294,5 +345,6 @@ AC_MSG_RESULT([ Ruby language binding: $rbzmq]) if test "x$rbzmq" = "xyes"; then AC_MSG_RESULT([ Ruby library install dir: $rubydir]) fi +AC_MSG_RESULT([ Java language binding: $jzmq]) AC_MSG_RESULT([]) diff --git a/java/Context.cpp b/java/Context.cpp new file mode 100644 index 0000000..d8fcf99 --- /dev/null +++ b/java/Context.cpp @@ -0,0 +1,92 @@ +/* + Copyright (c) 2007-2009 FastMQ Inc. + + This file is part of 0MQ. + + 0MQ is free software; you can redistribute it and/or modify it under + the terms of the Lesser GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + 0MQ is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + Lesser GNU General Public License for more details. + + You should have received a copy of the Lesser GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include + +#include "zmq.h" +#include "org_zmq_Context.h" + +static jfieldID ctx_handle_fid = NULL; + +static void +raise_exception (JNIEnv *env, int err) +{ + // Get exception class. + jclass exception_class = env->FindClass ("java/lang/Exception"); + assert (exception_class); + + // Get text description of the exception. + const char *err_msg = strerror (err); + + // Raise the exception. + int rc = env->ThrowNew (exception_class, err_msg); + assert (rc == 0); + + // Free the local ref. + env->DeleteLocalRef (exception_class); +} + +JNIEXPORT void JNICALL +Java_org_zmq_Context_construct (JNIEnv *env, jobject obj, + jint app_threads, jint io_threads) +{ + if (ctx_handle_fid == NULL) { + jclass cls = env->GetObjectClass (obj); + assert (cls); + ctx_handle_fid = env->GetFieldID (cls, "contextHandle", "J"); + assert (ctx_handle_fid); + env->DeleteLocalRef (cls); + } + + void *ctx = zmq_init (app_threads, io_threads); + if (ctx == NULL) { + raise_exception (env, errno); + return; + } + + env->SetLongField (obj, ctx_handle_fid, (jlong) ctx); +} + +JNIEXPORT void JNICALL +Java_org_zmq_Context_finalize (JNIEnv *env, jobject obj) +{ + void *ctx = (void*) env->GetLongField (obj, ctx_handle_fid); + assert (ctx); + + int rc = zmq_term (ctx); + assert (rc == 0); +} + +JNIEXPORT jlong JNICALL +Java_org_zmq_Context_createSocket (JNIEnv *env, jobject obj, jint type) +{ + void *ctx = (void*) env->GetLongField (obj, ctx_handle_fid); + assert (ctx); + + void *s = zmq_socket (ctx, type); + if (s == NULL) { + raise_exception (env, errno); + return -1; + } + + return (jlong) s; +} diff --git a/java/Makefile.am b/java/Makefile.am new file mode 100644 index 0000000..363f941 --- /dev/null +++ b/java/Makefile.am @@ -0,0 +1,72 @@ +# We do not want to install Jzmq.class file +# user has to copy it to the right location. +#jzmqdir = /tmp + +jarfile = Zmq.jar +jardir = $(datadir)/java + +$(jarfile): $(dist_noinst_JAVA) + $(JAR) cf $(JARFLAGS) $@ org/zmq/*.class + +jar_DATA = $(jarfile) + +dist_noinst_JAVA = \ + org/zmq/Context.java \ + org/zmq/Socket.java \ + org/zmq/Message.java + +lib_LTLIBRARIES = libjzmq.la +libjzmq_la_SOURCES = \ + Context.cpp \ + org_zmq_Context.h \ + Socket.cpp \ + org_zmq_Socket.h \ + Message.cpp \ + org_zmq_Message.h + +libjzmq_la_CXXFLAGS = -I$(top_builddir)/src/libzmq \ +@JAVA_INCLUDE@ -I$(top_builddir)/include -I$(top_srcdir)/libjzmq -Wall -I /usr/lib/jvm/java-6-openjdk/include +libjzmq_la_LDFLAGS = -version-info 0:0:0 +libjzmq_la_LIBADD = $(top_builddir)/src/libzmq.la + +BUILT_SOURCES = \ + org/zmq/Context.class \ + org_zmq_Context.h \ + org/zmq/Socket.class \ + org_zmq_Socket.h \ + org/zmq/Message.class \ + org_zmq_Message.h + +CLEANFILES = \ + org/zmq/Context.class \ + org_zmq_Context.h \ + org/zmq/Socket.class \ + org_zmq_Socket.h \ + org/zmq/Message.class \ + org_zmq_Message.h \ + Zmq.jar + +$(srcdir)/Context.cpp: org_zmq_Context.h + +org_zmq_Context.h: org/zmq/Context.class + $(CLASSPATH_ENV) $(JAVAH) -jni -classpath . org.zmq.Context + +./org/zmq/Context.class: classdist_noinst.stamp + +$(srcdir)/Socket.cpp: org_zmq_Socket.h + +org_zmq_Socket.h: org/zmq/Socket.class + $(CLASSPATH_ENV) $(JAVAH) -jni -classpath . org.zmq.Socket + +./org/zmq/Socket.class: classdist_noinst.stamp + +$(srcdir)/Message.cpp: org_zmq_Message.h + +org_zmq_Message.h: org/zmq/Message.class + $(CLASSPATH_ENV) $(JAVAH) -jni -classpath . org.zmq.Message + +./org/zmq/Message.class: classdist_noinst.stamp + +dist-hook: + -rm $(distdir)/*.h + diff --git a/java/Message.cpp b/java/Message.cpp new file mode 100644 index 0000000..2105216 --- /dev/null +++ b/java/Message.cpp @@ -0,0 +1,138 @@ +/* + Copyright (c) 2007-2009 FastMQ Inc. + + This file is part of 0MQ. + + 0MQ is free software; you can redistribute it and/or modify it under + the terms of the Lesser GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + 0MQ is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + Lesser GNU General Public License for more details. + + You should have received a copy of the Lesser GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include + +#include "zmq.h" +#include "org_zmq_Message.h" + +static jfieldID msg_handle_fid = NULL; + +static void +raise_exception (JNIEnv *env, int err) +{ + // Get exception class. + jclass exception_class = env->FindClass ("java/lang/Exception"); + assert (exception_class); + + // Get text description of the exception. + const char *err_msg = strerror (err); + + // Raise the exception. + int rc = env->ThrowNew (exception_class, err_msg); + assert (rc == 0); + + // Free the local ref. + env->DeleteLocalRef (exception_class); +} + +JNIEXPORT void JNICALL +Java_org_zmq_Message_construct (JNIEnv *env, jobject obj) +{ + if (msg_handle_fid == NULL) { + jclass cls = env->GetObjectClass (obj); + assert (cls != NULL); + msg_handle_fid = env->GetFieldID (cls, "msgHandle", "J"); + assert (msg_handle_fid != NULL); + env->DeleteLocalRef (cls); + } + + zmq_msg_t *msg = (zmq_msg_t*) malloc (sizeof (zmq_msg_t)); + if (msg == NULL) { + raise_exception (env, ENOMEM); + return; + } + + int rc = zmq_msg_init (msg); + assert (rc == 0); + env->SetLongField (obj, msg_handle_fid, (jlong) msg); +} + +JNIEXPORT void JNICALL +Java_org_zmq_Message_constructWithData (JNIEnv *env, jobject obj, + jbyteArray payload) +{ + if (msg_handle_fid == NULL) { + jclass cls = env->GetObjectClass (obj); + assert (cls != NULL); + msg_handle_fid = env->GetFieldID (cls, "msgHandle", "J"); + assert (msg_handle_fid != NULL); + env->DeleteLocalRef (cls); + } + + zmq_msg_t *msg = (zmq_msg_t*) malloc (sizeof (zmq_msg_t)); + if (msg == NULL) { + raise_exception (env, ENOMEM); + return; + } + + jsize array_size = env->GetArrayLength (payload); + jbyte *array_data = env->GetByteArrayElements (payload, NULL); + + int rc = zmq_msg_init_size (msg, array_size); + assert (rc == 0); + + memcpy (zmq_msg_data (msg), array_data, array_size); + env->ReleaseByteArrayElements (payload, array_data, JNI_ABORT); + + env->SetLongField (obj, msg_handle_fid, (jlong) msg); +} + +JNIEXPORT void JNICALL +Java_org_zmq_Message_finalize (JNIEnv *env, jobject obj) +{ + zmq_msg_t *msg = (zmq_msg_t*) env->GetLongField (obj, msg_handle_fid); + assert (msg); + + int rc = zmq_msg_close (msg); + assert (rc == 0); + + free (msg); +} + +JNIEXPORT jbyteArray JNICALL +Java_org_zmq_Message_getMsgPayload (JNIEnv *env, jobject obj) +{ + zmq_msg_t *msg = (zmq_msg_t*) env->GetLongField (obj, msg_handle_fid); + assert (msg); + + jsize msg_size = zmq_msg_size (msg); + jbyte *msg_data = (jbyte*) zmq_msg_data (msg); + + jbyteArray payload = env->NewByteArray (msg_size); + if (payload == NULL) + return NULL; + + env->SetByteArrayRegion (payload, 0, msg_size, msg_data); + assert (!env->ExceptionCheck ()); + + return payload; +} + +JNIEXPORT jint JNICALL +Java_org_zmq_Message_getMsgType (JNIEnv *env, jobject obj) +{ + zmq_msg_t *msg = (zmq_msg_t*) env->GetLongField (obj, msg_handle_fid); + assert (msg); + + return (jint) zmq_msg_type (msg); +} diff --git a/java/Socket.cpp b/java/Socket.cpp new file mode 100644 index 0000000..eb3c1e3 --- /dev/null +++ b/java/Socket.cpp @@ -0,0 +1,276 @@ +/* + Copyright (c) 2007-2009 FastMQ Inc. + + This file is part of 0MQ. + + 0MQ is free software; you can redistribute it and/or modify it under + the terms of the Lesser GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + 0MQ is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + Lesser GNU General Public License for more details. + + You should have received a copy of the Lesser GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include + +#include "zmq.h" +#include "org_zmq_Socket.h" + +static jfieldID socket_handle_fid = NULL; +static jclass msg_class = NULL; +static jmethodID msg_constructor; +static jmethodID get_msg_handle_mid = NULL; +static jmethodID create_socket_mid = NULL; + +static void +raise_exception (JNIEnv *env, int err) +{ + // Get exception class. + jclass exception_class = env->FindClass ("java/lang/Exception"); + assert (exception_class); + + // Get text description of the exception. + const char *err_msg = strerror (err); + + // Raise the exception. + int rc = env->ThrowNew (exception_class, err_msg); + assert (rc == 0); + + // Free the local ref. + env->DeleteLocalRef (exception_class); +} + +JNIEXPORT void JNICALL +Java_org_zmq_Socket_construct (JNIEnv *env, jobject obj, jobject context, + jint type) +{ + if (socket_handle_fid == NULL) { + jclass cls = env->GetObjectClass (obj); + assert (cls); + socket_handle_fid = env->GetFieldID (cls, "socketHandle", "J"); + assert (socket_handle_fid); + env->DeleteLocalRef (cls); + } + + if (create_socket_mid == NULL) { + jclass cls = env->FindClass ("org/zmq/Context"); + assert (cls); + create_socket_mid = env->GetMethodID (cls, "createSocket", "(I)J"); + assert (create_socket_mid); + env->DeleteLocalRef (cls); + } + + if (msg_class == NULL) { + jclass cls = env->FindClass ("org/zmq/Message"); + assert (cls); + + msg_constructor = env->GetMethodID (cls, "", "()V"); + assert (msg_constructor); + + get_msg_handle_mid = env->GetMethodID (cls, "getMsgHandle", "()J"); + assert (get_msg_handle_mid); + + msg_class = (jclass) env->NewGlobalRef (cls); + assert (msg_class); + env->DeleteLocalRef (cls); + } + + void *s = (void *) env->CallLongMethod (context, create_socket_mid, type); + if (env->ExceptionCheck ()) + return; + + env->SetLongField (obj, socket_handle_fid, (jlong) s); +} + +JNIEXPORT void JNICALL +Java_org_zmq_Socket_finalize (JNIEnv *env, jobject obj) +{ + void *s = (void*) env->GetLongField (obj, socket_handle_fid); + assert (s); + int rc = zmq_close (s); + assert (rc == 0); +} + +JNIEXPORT void JNICALL +Java_org_zmq_Socket_setHwm (JNIEnv *env, jobject obj, jlong hwm) +{ + void *s = (void*) env->GetLongField (obj, socket_handle_fid); + assert (s); + int rc = zmq_setsockopt (s, ZMQ_HWM, &hwm, sizeof hwm); + if (rc == -1) + raise_exception (env, errno); +} + +JNIEXPORT void JNICALL +Java_org_zmq_Socket_setLwm (JNIEnv *env, jobject obj, jlong lwm) +{ + void *s = (void*) env->GetLongField (obj, socket_handle_fid); + assert (s); + + int rc = zmq_setsockopt (s, ZMQ_LWM, &lwm, sizeof lwm); + if (rc == -1) + raise_exception (env, errno); +} + +JNIEXPORT void JNICALL +Java_org_zmq_Socket_setSwap (JNIEnv *env, jobject obj, jlong swap_size) +{ + void *s = (void*) env->GetLongField (obj, socket_handle_fid); + assert (s); + + int rc = zmq_setsockopt (s, ZMQ_SWAP, &swap_size, sizeof swap_size); + if (rc == -1) + raise_exception (env, errno); +} + +JNIEXPORT void JNICALL +Java_org_zmq_Socket_setMask (JNIEnv *env, jobject obj, jlong mask) +{ + void *s = (void*) env->GetLongField (obj, socket_handle_fid); + assert (s); + + int rc = zmq_setsockopt (s, ZMQ_MASK, &mask, sizeof mask); + if (rc == -1) + raise_exception (env, errno); +} + +JNIEXPORT void JNICALL +Java_org_zmq_Socket_setAffinity (JNIEnv *env, jobject obj, jlong affinity) +{ + void *s = (void*) env->GetLongField (obj, socket_handle_fid); + assert (s); + + int rc = zmq_setsockopt (s, ZMQ_AFFINITY, &affinity, sizeof affinity); + if (rc == -1) + raise_exception (env, errno); +} + +JNIEXPORT void JNICALL +Java_org_zmq_Socket_setIdentity (JNIEnv *env, jobject obj, jstring identity) +{ + void *s = (void*) env->GetLongField (obj, socket_handle_fid); + assert (s); + + if (identity == NULL) { + raise_exception (env, EINVAL); + return; + } + + const char *c_identity = env->GetStringUTFChars (identity, NULL); + if (c_identity == NULL) + return; + + int rc = zmq_setsockopt (s, ZMQ_IDENTITY, c_identity, sizeof c_identity); + env->ReleaseStringUTFChars (identity, c_identity); + + if (rc == -1) + raise_exception (env, errno); +} + +JNIEXPORT void JNICALL +Java_org_zmq_Socket_bind (JNIEnv *env, jobject obj, jstring addr) +{ + void *s = (void*) env->GetLongField (obj, socket_handle_fid); + assert (s); + + if (addr == NULL) { + raise_exception (env, EINVAL); + return; + } + + const char *c_addr = env->GetStringUTFChars (addr, NULL); + if (c_addr == NULL) + return; + + int rc = zmq_bind (s, c_addr); + env->ReleaseStringUTFChars (addr, c_addr); + + if (rc == -1) + raise_exception (env, errno); +} + +JNIEXPORT void JNICALL +Java_org_zmq_Socket_connect (JNIEnv *env, jobject obj, jstring addr) +{ + void *s = (void*) env->GetLongField (obj, socket_handle_fid); + assert (s); + + if (addr == NULL) { + raise_exception (env, EINVAL); + return; + } + + const char *c_addr = env->GetStringUTFChars (addr, NULL); + if (c_addr == NULL) + return; + + int rc = zmq_connect (s, c_addr); + env->ReleaseStringUTFChars (addr, c_addr); + + if (rc == -1) + raise_exception (env, errno); +} + +JNIEXPORT jint JNICALL +Java_org_zmq_Socket_send (JNIEnv *env, jobject obj, jobject msg, jlong flags) +{ + void *s = (void*) env->GetLongField (obj, socket_handle_fid); + assert (s); + + zmq_msg_t *zmq_msg = (zmq_msg_t *) + env->CallLongMethod (msg, get_msg_handle_mid); + + if (env->ExceptionCheck ()) + return -1; + + int rc = zmq_send (s, zmq_msg, (int) flags); + if (rc == -1) { + raise_exception (env, errno); + return -1; + } + + return rc; +} + +JNIEXPORT void JNICALL +Java_org_zmq_Socket_flush (JNIEnv *env, jobject obj) +{ + void *s = (void*) env->GetLongField (obj, socket_handle_fid); + assert (s); + + zmq_flush (s); +} + +JNIEXPORT jobject JNICALL +Java_org_zmq_Socket_recv (JNIEnv *env, jobject obj, jlong flags) +{ + void *s = (void*) env->GetLongField (obj, socket_handle_fid); + assert (s); + + jobject msg = env->NewObject (msg_class, msg_constructor); + if (msg == NULL) + return NULL; + + zmq_msg_t *zmq_msg = (zmq_msg_t*) + env->CallLongMethod (msg, get_msg_handle_mid); + + if (env->ExceptionCheck ()) + return NULL; + + int rc = zmq_recv (s, zmq_msg, (int) flags); + if (rc == -1) { + raise_exception (env, errno); + return NULL; + } + + return msg; +} diff --git a/java/org/zmq/Context.java b/java/org/zmq/Context.java new file mode 100644 index 0000000..8bc4d57 --- /dev/null +++ b/java/org/zmq/Context.java @@ -0,0 +1,47 @@ +/* + Copyright (c) 2007-2009 FastMQ Inc. + + This file is part of 0MQ. + + 0MQ is free software; you can redistribute it and/or modify it under + the terms of the Lesser GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + 0MQ is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + Lesser GNU General Public License for more details. + + You should have received a copy of the Lesser GNU General Public License + along with this program. If not, see . +*/ + +package org.zmq; + +public class Context { + static { + System.loadLibrary("jzmq"); + } + + /** + * Class constructor. + * + * @param appThreads maximum number of application threads. + * @param ioThreads size of the threads pool to handle I/O operations. + */ + public Context (int appThreads, int ioThreads) { + construct (appThreads, ioThreads); + } + + public native long createSocket (int type); + + /** Initialize the JNI interface */ + protected native void construct (int appThreads, int ioThreads); + + /** Free resources used by JNI driver. */ + protected native void finalize (); + + /** Opaque data used by JNI driver. */ + private long contextHandle; +} diff --git a/java/org/zmq/Message.java b/java/org/zmq/Message.java new file mode 100644 index 0000000..3691410 --- /dev/null +++ b/java/org/zmq/Message.java @@ -0,0 +1,66 @@ +/* + Copyright (c) 2007-2009 FastMQ Inc. + + This file is part of 0MQ. + + 0MQ is free software; you can redistribute it and/or modify it under + the terms of the Lesser GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + 0MQ is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + Lesser GNU General Public License for more details. + + You should have received a copy of the Lesser GNU General Public License + along with this program. If not, see . +*/ + +package org.zmq; + +public class Message { + static { + System.loadLibrary("jzmq"); + } + + /** + * Class constructor. + */ + public Message () { + construct (); + } + + public Message (byte [] payload) { + constructWithData (payload); + } + + /** + * Get message payload. + */ + public native byte [] getMsgPayload (); + + /** + * Get message type. + */ + public native int getMsgType (); + + /** + * Get low-level message handler. + */ + public long getMsgHandle () { + return msgHandle; + } + + /** Initialize the JNI interface */ + protected native void construct (); + + protected native void constructWithData (byte [] payload); + + /** Free resources used by JNI driver. */ + protected native void finalize (); + + /** Opaque data used by JNI driver. */ + private long msgHandle; +} + diff --git a/java/org/zmq/Socket.java b/java/org/zmq/Socket.java new file mode 100644 index 0000000..3bfbfec --- /dev/null +++ b/java/org/zmq/Socket.java @@ -0,0 +1,141 @@ +/* + Copyright (c) 2007-2009 FastMQ Inc. + + This file is part of 0MQ. + + 0MQ is free software; you can redistribute it and/or modify it under + the terms of the Lesser GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + 0MQ is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + Lesser GNU General Public License for more details. + + You should have received a copy of the Lesser GNU General Public License + along with this program. If not, see . +*/ + +package org.zmq; + +public class Socket { + static { + System.loadLibrary("jzmq"); + } + + public static final int ZMQ_MAX_VSM_SIZE = 30; + + public static final int ZMQ_GAP = 1; + + public static final int ZMQ_DELIMITER = 31; + + public static final int ZMQ_NOBLOCK = 1; + + public static final int ZMQ_NOFLUSH = 2; + + public static final int ZMQ_P2P = 0; + + public static final int ZMQ_PUB = 1; + + public static final int ZMQ_SUB = 2; + + /** + * Class constructor. + * + * @param context + * @param type + */ + public Socket (Context context, int type) { + ctx = context; + construct (context, type); + } + + /** + * Set the high watermark on the socket. + * + * @param hwm high watermark. + */ + public native void setHwm (long hwm); + + /** + * Set the low watermark on the socket. + * + * @param lwm low watermark. + */ + public native void setLwm (long lwm); + + /** + * Set swap size. + * + * @param swap_size swap size. + */ + public native void setSwap (long swap_size); + + /** + * Set reception mask. + * + * @param mask mask. + */ + public native void setMask (long mask); + + /** + * Set affinity. + * + * @param affinity + */ + public native void setAffinity (long affinity); + + /** + * Set identity. + * + * @param identity + */ + public native void setIdentity (String identity); + + /** + * @param addr + */ + public native void bind (String addr); + + /** + * Connect. + * + * @param addr + */ + public native void connect (String addr); + + /** + * Send. + * + * @param message + * @param block + */ + public native int send (Message msg, long flags); + + /** + * Flush all messages sent with flush flag false down the stream. + */ + public native void flush (); + + /** + * Receive message. + * + * @param block + * @return + */ + public native Message recv (long flags); + + /** Initialize JNI driver */ + protected native void construct (Context context, int type); + + /** Free all resources used by JNI driver. */ + protected native void finalize (); + + /** Keep reference to ZMQ context so it is not garbage collected */ + private Context ctx; + + /** Opaque data used by JNI driver. */ + private long socketHandle; + +} -- cgit v1.2.3