📄 jump_os_impl.c
字号:
/* * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program 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 GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */#include <jni.h>#include <stdlib.h>#include <string.h>#include "porting/JUMPMessageQueue.h"#include "porting/JUMPProcess.h"#include "jump_messaging.h"#include "jni_util.h"static jboolean messaging_started = JNI_FALSE;static void ensureInitialized() { /* * FIXME: * This is really for stand-alone execution. * We should really make this part of JVM initialization. */ if (!messaging_started) { jumpMessageStart(); messaging_started = JNI_TRUE; }}/* Throws exceptions with no-arg constructors, for which we can't use JNU_ThrowByName which constructs with a String arg. */static voidthrow_by_name(JNIEnv *env, const char *class_name){ jobject ex = JNU_NewObjectByName(env, class_name, "()V"); if (ex == NULL) { return; } (*env)->Throw(env, ex); (*env)->DeleteLocalRef(env, ex);}static voidthrow_with_messagetype(JNIEnv *env, const char *class_name, const char *type){ char message[80]; int len = sizeof(message) - 30; snprintf(message, sizeof(message), "messageType type=%.*s%s", len, type, strlen(type) > len ? "..." : ""); JNU_ThrowByName(env, class_name, message);}static const char *code_to_string(JUMPMessageStatusCode code){ switch (code) { case JUMP_TARGET_NONEXISTENT: return "JUMP_TARGET_NONEXISTENT"; case JUMP_TIMEOUT: return "JUMP_TIMEOUT"; case JUMP_SUCCESS: return "JUMP_SUCCESS"; case JUMP_FAILURE: return "JUMP_FAILURE"; case JUMP_OUT_OF_MEMORY: return "JUMP_OUT_OF_MEMORY"; case JUMP_WOULD_BLOCK: return "JUMP_WOULD_BLOCK"; case JUMP_OVERRUN: return "JUMP_OVERRUN"; case JUMP_NEGATIVE_ARRAY_LENGTH: return "JUMP_NEGATIVE_ARRAY_LENGTH"; case JUMP_UNBLOCKED: return "JUMP_UNBLOCKED"; case JUMP_NO_SUCH_QUEUE: return "JUMP_NO_SUCH_QUEUE"; default: return NULL; }}/* Throws a generic IOException with a message like "JUMPMessageStatusCode: N". This is for exceptions we're not expecting or exceptions that don't need specific reporting. */static voidthrow_IOException(JNIEnv *env, JUMPMessageStatusCode code){ const char *code_string; char code_string_buf[16]; char message[80]; code_string = code_to_string(code); if (code_string == NULL) { snprintf(code_string_buf, sizeof(code_string_buf), "%d", code); code_string = code_string_buf; } snprintf(message, sizeof(message), "JUMPMessageStatusCode: %s", code_string); JNU_ThrowByName(env, "java/io/IOException", message);}JNIEXPORT jint JNICALLJava_com_sun_jumpimpl_os_JUMPOSInterfaceImpl_getProcessID(JNIEnv *env, jobject thisObj){ return jumpProcessGetId();}JNIEXPORT jint JNICALLJava_com_sun_jumpimpl_os_JUMPOSInterfaceImpl_getExecutiveProcessID(JNIEnv *env, jobject thisObj){ return jumpProcessGetExecutiveId();}JNIEXPORT jint JNICALLJava_com_sun_jumpimpl_os_JUMPMessageQueueInterfaceImpl_getDataOffset(JNIEnv *env, jobject thisObj){ ensureInitialized(); return jumpMessageQueueDataOffset();}JNIEXPORT jstring JNICALLJava_com_sun_jumpimpl_os_JUMPMessageQueueInterfaceImpl_getReturnType(JNIEnv *env, jobject thisObj){ char* name; jstring ret; ensureInitialized(); name = jumpMessageGetReturnTypeName(); if (name == NULL) { JNU_ThrowOutOfMemoryError(env, "in jumpMessageGetReturnTypeName"); return NULL; } ret = (*env)->NewStringUTF(env, name); free(name); return ret;}/* On success, returns a new JUMPOutgoingMessage. On failure, returns NULL and throws an OutOfMemoryError or IOException. */static JUMPOutgoingMessagenew_outgoing_message_from_byte_array( JNIEnv *env, jbyteArray messageBytes, jboolean isResponse){ jbyte *buffer = NULL; jsize length; JUMPOutgoingMessage m; JUMPMessageStatusCode code; length = (*env)->GetArrayLength(env, messageBytes); if (length > JUMP_MESSAGE_BUFFER_SIZE) { JNU_ThrowByName(env, "java/io/IOException", "Maximum message size exceeded."); goto error; } buffer = malloc(JUMP_MESSAGE_BUFFER_SIZE); if (buffer == NULL) { JNU_ThrowOutOfMemoryError(env, "in new_outgoing_message_from_byte_array"); goto error; } (*env)->GetByteArrayRegion(env, messageBytes, 0, length, buffer); if ((*env)->ExceptionOccurred(env) != NULL) { goto error; } m = jumpMessageNewOutgoingFromBuffer(buffer, isResponse, &code); if (m == NULL) { switch (code) { case JUMP_OUT_OF_MEMORY: JNU_ThrowOutOfMemoryError(env, "in jumpMessageNewOutgoingFromBuffer"); break; default: throw_IOException(env, code); break; } goto error; } return m; error: free(buffer); return NULL;}/* On success, returns a new jbyteArray. On failure, returns NULL and throws an Exception. */static jbyteArraynew_byte_array_from_message( JNIEnv *env, JUMPMessage message){ jbyteArray retVal; retVal = (*env)->NewByteArray(env, JUMP_MESSAGE_BUFFER_SIZE); if (retVal == NULL) { return NULL; } (*env)->SetByteArrayRegion(env, retVal, 0, JUMP_MESSAGE_BUFFER_SIZE, jumpMessageGetData(message)); if ((*env)->ExceptionOccurred(env)) { (*env)->DeleteLocalRef(env, retVal); return NULL; } return retVal;}JNIEXPORT jbyteArray JNICALLJava_com_sun_jumpimpl_os_JUMPMessageQueueInterfaceImpl_sendMessageSync( JNIEnv *env, jobject thisObj, jint pid, jbyteArray messageBytes, jboolean isResponse, jlong timeout){ jbyteArray retVal = NULL; JUMPOutgoingMessage m = NULL; JUMPAddress target; JUMPMessage r = NULL; JUMPMessageStatusCode code; ensureInitialized(); m = new_outgoing_message_from_byte_array(env, messageBytes, isResponse); if (m == NULL) { /* Exception already thrown. */ goto out; } target.processId = pid; r = jumpMessageSendSync(target, m, (int32)timeout, &code); if (r == NULL) { switch (code) { case JUMP_OUT_OF_MEMORY: JNU_ThrowOutOfMemoryError(env, "in jumpMessageSendSync"); break; case JUMP_TARGET_NONEXISTENT: throw_with_messagetype( env, "com/sun/jump/message/JUMPTargetNonexistentException", jumpMessageGetType(m)); break; case JUMP_WOULD_BLOCK: throw_with_messagetype( env, "com/sun/jump/message/JUMPWouldBlockException", jumpMessageGetType(m)); break; case JUMP_TIMEOUT: throw_by_name(env, "com/sun/jump/message/JUMPTimedOutException"); break; case JUMP_UNBLOCKED: // This shouldn't happen here, unblocked is only for message // queues with registered handlers. // Fall through to default. default: throw_IOException(env, code); break; } goto out; } retVal = new_byte_array_from_message(env, r); if (retVal == NULL) { /* Exception already thrown. */ goto out; } out: if (r != NULL) { jumpMessageFree(r); } if (m != NULL) { jumpMessageFreeOutgoing(m); } return retVal;}JNIEXPORT jbyteArray JNICALLJava_com_sun_jumpimpl_os_JUMPMessageQueueInterfaceImpl_receiveMessage( JNIEnv *env, jobject thisObj, jstring messageType, jlong timeout){ const char* type = NULL; JUMPMessage r = NULL; JUMPMessageStatusCode code; jbyteArray retVal = NULL; ensureInitialized(); type = (*env)->GetStringUTFChars(env, messageType, NULL); if (type == NULL) { goto out; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -