Unregister all previous registered native methods if loading of native code fails… (#10719)
Motivation: It's important to unload all previous registered native methods when there is a failure during loading the native lib. Failing to do so may lead to an "invalid state" and so may segfault the JVM when trying to call a native method that was previous loaded. This was observed when two versions of netty-tcnative were on the classpath which had different requirements in terms of linking. Something like this was reported in he hs log: ``` Instructions: (pc=0x0000000116413bf0) 0x0000000116413bd0: [error occurred during error reporting (printing registers, top of stack, instructions near pc), id 0xb] Register to memory mapping: RAX=0x0000000116413bf0 is an unknown value RBX={method} {0x000000011422e708} 'aprMajorVersion' '()I' in 'io/netty/internal/tcnative/Library' RCX=0x000000000000000a is an unknown value RDX=0x000000000000000a is an unknown value ``` Modifications: - Unregister previous registered native methods on failure - Unregister previous registered native methods on on unload of the native lib Result: No more segfault caused by invalid state when loading of the native lib fails in between. In this case the user will receive an error now like:
This commit is contained in:
parent
56c47e4361
commit
31ffe11e47
@ -35,6 +35,8 @@
|
||||
#include "netty_unix_socket.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
#define LINUXSOCKET_CLASSNAME "io/netty/channel/epoll/LinuxSocket"
|
||||
|
||||
// TCP_FASTOPEN is defined in linux 3.7. We define this here so older kernels can compile.
|
||||
#ifndef TCP_FASTOPEN
|
||||
#define TCP_FASTOPEN 23
|
||||
@ -755,7 +757,7 @@ jint netty_epoll_linuxsocket_JNI_OnLoad(JNIEnv* env, const char* packagePrefix)
|
||||
}
|
||||
if (netty_unix_util_register_natives(env,
|
||||
packagePrefix,
|
||||
"io/netty/channel/epoll/LinuxSocket",
|
||||
LINUXSOCKET_CLASSNAME,
|
||||
dynamicMethods,
|
||||
dynamicMethodsTableSize()) != 0) {
|
||||
goto done;
|
||||
@ -788,6 +790,8 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void netty_epoll_linuxsocket_JNI_OnUnLoad(JNIEnv* env) {
|
||||
void netty_epoll_linuxsocket_JNI_OnUnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
NETTY_UNLOAD_CLASS(env, peerCredentialsClass);
|
||||
|
||||
netty_unix_util_unregister_natives(env, packagePrefix, LINUXSOCKET_CLASSNAME);
|
||||
}
|
||||
|
@ -21,6 +21,6 @@
|
||||
|
||||
// JNI initialization hooks. Users of this file are responsible for calling these in the JNI_OnLoad and JNI_OnUnload methods.
|
||||
jint netty_epoll_linuxsocket_JNI_OnLoad(JNIEnv* env, const char* packagePrefix);
|
||||
void netty_epoll_linuxsocket_JNI_OnUnLoad(JNIEnv* env);
|
||||
void netty_epoll_linuxsocket_JNI_OnUnLoad(JNIEnv* env, const char* packagePrefix);
|
||||
|
||||
#endif
|
||||
|
@ -49,6 +49,9 @@
|
||||
#include "netty_unix_socket.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
#define STATICALLY_CLASSNAME "io/netty/channel/epoll/NativeStaticallyReferencedJniMethods"
|
||||
#define NATIVE_CLASSNAME "io/netty/channel/epoll/Native"
|
||||
|
||||
// TCP_FASTOPEN is defined in linux 3.7. We define this here so older kernels can compile.
|
||||
#ifndef TCP_FASTOPEN
|
||||
#define TCP_FASTOPEN 23
|
||||
@ -98,6 +101,7 @@ static jfieldID packetScopeIdFieldId = NULL;
|
||||
static jfieldID packetPortFieldId = NULL;
|
||||
static jfieldID packetMemoryAddressFieldId = NULL;
|
||||
static jfieldID packetCountFieldId = NULL;
|
||||
static char* staticPackagePrefix = NULL;
|
||||
|
||||
// util methods
|
||||
static int getSysctlValue(const char * property, int* returnValue) {
|
||||
@ -564,6 +568,8 @@ error:
|
||||
|
||||
static jint netty_epoll_native_JNI_OnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
int ret = JNI_ERR;
|
||||
int staticallyRegistered = 0;
|
||||
int nativeRegistered = 0;
|
||||
int limitsOnLoadCalled = 0;
|
||||
int errorsOnLoadCalled = 0;
|
||||
int filedescriptorOnLoadCalled = 0;
|
||||
@ -577,11 +583,13 @@ static jint netty_epoll_native_JNI_OnLoad(JNIEnv* env, const char* packagePrefix
|
||||
// We must register the statically referenced methods first!
|
||||
if (netty_unix_util_register_natives(env,
|
||||
packagePrefix,
|
||||
"io/netty/channel/epoll/NativeStaticallyReferencedJniMethods",
|
||||
STATICALLY_CLASSNAME,
|
||||
statically_referenced_fixed_method_table,
|
||||
statically_referenced_fixed_method_table_size) != 0) {
|
||||
goto done;
|
||||
}
|
||||
staticallyRegistered = 1;
|
||||
|
||||
// Register the methods which are not referenced by static member variables
|
||||
dynamicMethods = createDynamicMethodsTable(packagePrefix);
|
||||
if (dynamicMethods == NULL) {
|
||||
@ -590,11 +598,13 @@ static jint netty_epoll_native_JNI_OnLoad(JNIEnv* env, const char* packagePrefix
|
||||
|
||||
if (netty_unix_util_register_natives(env,
|
||||
packagePrefix,
|
||||
"io/netty/channel/epoll/Native",
|
||||
NATIVE_CLASSNAME,
|
||||
dynamicMethods,
|
||||
dynamicMethodsTableSize()) != 0) {
|
||||
goto done;
|
||||
}
|
||||
nativeRegistered = 1;
|
||||
|
||||
// Load all c modules that we depend upon
|
||||
if (netty_unix_limits_JNI_OnLoad(env, packagePrefix) == JNI_ERR) {
|
||||
goto done;
|
||||
@ -645,23 +655,29 @@ done:
|
||||
free(nettyClassName);
|
||||
|
||||
if (ret == JNI_ERR) {
|
||||
if (staticallyRegistered == 1) {
|
||||
netty_unix_util_unregister_natives(env, packagePrefix, STATICALLY_CLASSNAME);
|
||||
}
|
||||
if (nativeRegistered == 1) {
|
||||
netty_unix_util_unregister_natives(env, packagePrefix, NATIVE_CLASSNAME);
|
||||
}
|
||||
if (limitsOnLoadCalled == 1) {
|
||||
netty_unix_limits_JNI_OnUnLoad(env);
|
||||
netty_unix_limits_JNI_OnUnLoad(env, packagePrefix);
|
||||
}
|
||||
if (errorsOnLoadCalled == 1) {
|
||||
netty_unix_errors_JNI_OnUnLoad(env);
|
||||
netty_unix_errors_JNI_OnUnLoad(env, packagePrefix);
|
||||
}
|
||||
if (filedescriptorOnLoadCalled == 1) {
|
||||
netty_unix_filedescriptor_JNI_OnUnLoad(env);
|
||||
netty_unix_filedescriptor_JNI_OnUnLoad(env, packagePrefix);
|
||||
}
|
||||
if (socketOnLoadCalled == 1) {
|
||||
netty_unix_socket_JNI_OnUnLoad(env);
|
||||
netty_unix_socket_JNI_OnUnLoad(env, packagePrefix);
|
||||
}
|
||||
if (bufferOnLoadCalled == 1) {
|
||||
netty_unix_buffer_JNI_OnUnLoad(env);
|
||||
netty_unix_buffer_JNI_OnUnLoad(env, packagePrefix);
|
||||
}
|
||||
if (linuxsocketOnLoadCalled == 1) {
|
||||
netty_epoll_linuxsocket_JNI_OnUnLoad(env);
|
||||
netty_epoll_linuxsocket_JNI_OnUnLoad(env, packagePrefix);
|
||||
}
|
||||
packetAddrFieldId = NULL;
|
||||
packetAddrLenFieldId = NULL;
|
||||
@ -673,13 +689,13 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void netty_epoll_native_JNI_OnUnLoad(JNIEnv* env) {
|
||||
netty_unix_limits_JNI_OnUnLoad(env);
|
||||
netty_unix_errors_JNI_OnUnLoad(env);
|
||||
netty_unix_filedescriptor_JNI_OnUnLoad(env);
|
||||
netty_unix_socket_JNI_OnUnLoad(env);
|
||||
netty_unix_buffer_JNI_OnUnLoad(env);
|
||||
netty_epoll_linuxsocket_JNI_OnUnLoad(env);
|
||||
static void netty_epoll_native_JNI_OnUnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
netty_unix_limits_JNI_OnUnLoad(env, packagePrefix);
|
||||
netty_unix_errors_JNI_OnUnLoad(env, packagePrefix);
|
||||
netty_unix_filedescriptor_JNI_OnUnLoad(env, packagePrefix);
|
||||
netty_unix_socket_JNI_OnUnLoad(env, packagePrefix);
|
||||
netty_unix_buffer_JNI_OnUnLoad(env, packagePrefix);
|
||||
netty_epoll_linuxsocket_JNI_OnUnLoad(env, packagePrefix);
|
||||
|
||||
packetAddrFieldId = NULL;
|
||||
packetAddrLenFieldId = NULL;
|
||||
@ -687,6 +703,9 @@ static void netty_epoll_native_JNI_OnUnLoad(JNIEnv* env) {
|
||||
packetPortFieldId = NULL;
|
||||
packetMemoryAddressFieldId = NULL;
|
||||
packetCountFieldId = NULL;
|
||||
|
||||
netty_unix_util_unregister_natives(env, packagePrefix, STATICALLY_CLASSNAME);
|
||||
netty_unix_util_unregister_natives(env, packagePrefix, NATIVE_CLASSNAME);
|
||||
}
|
||||
|
||||
// Invoked by the JVM when statically linked
|
||||
@ -712,8 +731,12 @@ static jint JNI_OnLoad_netty_transport_native_epoll0(JavaVM* vm, void* reserved)
|
||||
}
|
||||
#endif /* NETTY_BUILD_STATIC */
|
||||
jint ret = netty_epoll_native_JNI_OnLoad(env, packagePrefix);
|
||||
|
||||
free(packagePrefix);
|
||||
if (ret == JNI_ERR) {
|
||||
free(packagePrefix);
|
||||
staticPackagePrefix = NULL;
|
||||
} else {
|
||||
staticPackagePrefix = packagePrefix;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -723,7 +746,9 @@ static void JNI_OnUnload_netty_transport_native_epoll0(JavaVM* vm, void* reserve
|
||||
// Something is wrong but nothing we can do about this :(
|
||||
return;
|
||||
}
|
||||
netty_epoll_native_JNI_OnUnLoad(env);
|
||||
netty_epoll_native_JNI_OnUnLoad(env, staticPackagePrefix);
|
||||
free(staticPackagePrefix);
|
||||
staticPackagePrefix = NULL;
|
||||
}
|
||||
|
||||
// We build with -fvisibility=hidden so ensure we mark everything that needs to be visible with JNIEXPORT
|
||||
|
@ -32,6 +32,8 @@
|
||||
#include "netty_unix_socket.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
#define BSDSOCKET_CLASSNAME "io/netty/channel/kqueue/BsdSocket"
|
||||
|
||||
// Those are initialized in the init(...) method and cached for performance reasons
|
||||
static jclass stringClass = NULL;
|
||||
static jclass peerCredentialsClass = NULL;
|
||||
@ -249,7 +251,7 @@ jint netty_kqueue_bsdsocket_JNI_OnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
}
|
||||
if (netty_unix_util_register_natives(env,
|
||||
packagePrefix,
|
||||
"io/netty/channel/kqueue/BsdSocket",
|
||||
BSDSOCKET_CLASSNAME,
|
||||
dynamicMethods,
|
||||
dynamicMethodsTableSize()) != 0) {
|
||||
goto done;
|
||||
@ -284,7 +286,9 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void netty_kqueue_bsdsocket_JNI_OnUnLoad(JNIEnv* env) {
|
||||
void netty_kqueue_bsdsocket_JNI_OnUnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
NETTY_UNLOAD_CLASS(env, peerCredentialsClass);
|
||||
NETTY_UNLOAD_CLASS(env, stringClass);
|
||||
|
||||
netty_unix_util_unregister_natives(env, packagePrefix, BSDSOCKET_CLASSNAME);
|
||||
}
|
||||
|
@ -20,6 +20,6 @@
|
||||
|
||||
// JNI initialization hooks. Users of this file are responsible for calling these in the JNI_OnLoad and JNI_OnUnload methods.
|
||||
jint netty_kqueue_bsdsocket_JNI_OnLoad(JNIEnv* env, const char* packagePrefix);
|
||||
void netty_kqueue_bsdsocket_JNI_OnUnLoad(JNIEnv* env);
|
||||
void netty_kqueue_bsdsocket_JNI_OnUnLoad(JNIEnv* env, const char* packagePrefix);
|
||||
|
||||
#endif /* NETTY_KQUEUE_BSDSOCKET_H_ */
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include "netty_unix_jni.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
#define EVENT_ARRAY_CLASSNAME "io/netty/channel/kqueue/KQueueEventArray"
|
||||
|
||||
static void netty_kqueue_eventarray_evSet(JNIEnv* env, jclass clzz, jlong keventAddress, jint ident, jshort filter, jshort flags, jint fflags) {
|
||||
EV_SET((struct kevent*) keventAddress, ident, filter, flags, fflags, 0, NULL);
|
||||
}
|
||||
@ -39,7 +41,7 @@ static const jint fixed_method_table_size = sizeof(fixed_method_table) / sizeof(
|
||||
jint netty_kqueue_eventarray_JNI_OnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
if (netty_unix_util_register_natives(env,
|
||||
packagePrefix,
|
||||
"io/netty/channel/kqueue/KQueueEventArray",
|
||||
EVENT_ARRAY_CLASSNAME,
|
||||
fixed_method_table,
|
||||
fixed_method_table_size) != 0) {
|
||||
return JNI_ERR;
|
||||
@ -47,5 +49,6 @@ jint netty_kqueue_eventarray_JNI_OnLoad(JNIEnv* env, const char* packagePrefix)
|
||||
return NETTY_JNI_VERSION;
|
||||
}
|
||||
|
||||
void netty_kqueue_eventarray_JNI_OnUnLoad(JNIEnv* env) {
|
||||
void netty_kqueue_eventarray_JNI_OnUnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
netty_unix_util_unregister_natives(env, packagePrefix, EVENT_ARRAY_CLASSNAME);
|
||||
}
|
||||
|
@ -20,6 +20,6 @@
|
||||
|
||||
// JNI initialization hooks. Users of this file are responsible for calling these in the JNI_OnLoad and JNI_OnUnload methods.
|
||||
jint netty_kqueue_eventarray_JNI_OnLoad(JNIEnv* env, const char* packagePrefix);
|
||||
void netty_kqueue_eventarray_JNI_OnUnLoad(JNIEnv* env);
|
||||
void netty_kqueue_eventarray_JNI_OnUnLoad(JNIEnv* env, const char* packagePrefix);
|
||||
|
||||
#endif /* NETTY_KQUEUE_EVENTARRAY_H_ */
|
||||
|
@ -36,6 +36,9 @@
|
||||
#include "netty_unix_socket.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
#define STATICALLY_CLASSNAME "io/netty/channel/kqueue/KQueueStaticallyReferencedJniMethods"
|
||||
#define NATIVE_CLASSNAME "io/netty/channel/kqueue/Native"
|
||||
|
||||
// Currently only macOS supports EVFILT_SOCK, and it is currently only available in internal APIs.
|
||||
// To make compiling easier we redefine the values here if they are not present.
|
||||
#ifdef __APPLE__
|
||||
@ -68,6 +71,8 @@
|
||||
|
||||
static clockid_t waitClockId = 0; // initialized by netty_unix_util_initialize_wait_clock
|
||||
|
||||
static char* staticPackagePrefix;
|
||||
|
||||
static jint netty_kqueue_native_kqueueCreate(JNIEnv* env, jclass clazz) {
|
||||
jint kq = kqueue();
|
||||
if (kq < 0) {
|
||||
@ -265,6 +270,8 @@ static const jint fixed_method_table_size = sizeof(fixed_method_table) / sizeof(
|
||||
// JNI Method Registration Table End
|
||||
|
||||
static jint netty_kqueue_native_JNI_OnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
int staticallyRegistered = 0;
|
||||
int nativeRegistered = 0;
|
||||
int limitsOnLoadCalled = 0;
|
||||
int errorsOnLoadCalled = 0;
|
||||
int filedescriptorOnLoadCalled = 0;
|
||||
@ -276,15 +283,19 @@ static jint netty_kqueue_native_JNI_OnLoad(JNIEnv* env, const char* packagePrefi
|
||||
// We must register the statically referenced methods first!
|
||||
if (netty_unix_util_register_natives(env,
|
||||
packagePrefix,
|
||||
"io/netty/channel/kqueue/KQueueStaticallyReferencedJniMethods",
|
||||
STATICALLY_CLASSNAME,
|
||||
statically_referenced_fixed_method_table,
|
||||
statically_referenced_fixed_method_table_size) != 0) {
|
||||
goto error;
|
||||
}
|
||||
staticallyRegistered = 1;
|
||||
|
||||
// Register the methods which are not referenced by static member variables
|
||||
if (netty_unix_util_register_natives(env, packagePrefix, "io/netty/channel/kqueue/Native", fixed_method_table, fixed_method_table_size) != 0) {
|
||||
if (netty_unix_util_register_natives(env, packagePrefix, NATIVE_CLASSNAME, fixed_method_table, fixed_method_table_size) != 0) {
|
||||
goto error;
|
||||
}
|
||||
nativeRegistered = 1;
|
||||
|
||||
// Load all c modules that we depend upon
|
||||
if (netty_unix_limits_JNI_OnLoad(env, packagePrefix) == JNI_ERR) {
|
||||
goto error;
|
||||
@ -330,38 +341,44 @@ static jint netty_kqueue_native_JNI_OnLoad(JNIEnv* env, const char* packagePrefi
|
||||
|
||||
return NETTY_JNI_VERSION;
|
||||
error:
|
||||
if (staticallyRegistered == 1) {
|
||||
netty_unix_util_unregister_natives(env, packagePrefix, STATICALLY_CLASSNAME);
|
||||
}
|
||||
if (nativeRegistered == 1) {
|
||||
netty_unix_util_unregister_natives(env, packagePrefix, NATIVE_CLASSNAME);
|
||||
}
|
||||
if (limitsOnLoadCalled == 1) {
|
||||
netty_unix_limits_JNI_OnUnLoad(env);
|
||||
netty_unix_limits_JNI_OnUnLoad(env, packagePrefix);
|
||||
}
|
||||
if (errorsOnLoadCalled == 1) {
|
||||
netty_unix_errors_JNI_OnUnLoad(env);
|
||||
netty_unix_errors_JNI_OnUnLoad(env, packagePrefix);
|
||||
}
|
||||
if (filedescriptorOnLoadCalled == 1) {
|
||||
netty_unix_filedescriptor_JNI_OnUnLoad(env);
|
||||
netty_unix_filedescriptor_JNI_OnUnLoad(env, packagePrefix);
|
||||
}
|
||||
if (socketOnLoadCalled == 1) {
|
||||
netty_unix_socket_JNI_OnUnLoad(env);
|
||||
netty_unix_socket_JNI_OnUnLoad(env, packagePrefix);
|
||||
}
|
||||
if (bufferOnLoadCalled == 1) {
|
||||
netty_unix_buffer_JNI_OnUnLoad(env);
|
||||
netty_unix_buffer_JNI_OnUnLoad(env, packagePrefix);
|
||||
}
|
||||
if (bsdsocketOnLoadCalled == 1) {
|
||||
netty_kqueue_bsdsocket_JNI_OnUnLoad(env);
|
||||
netty_kqueue_bsdsocket_JNI_OnUnLoad(env, packagePrefix);
|
||||
}
|
||||
if (eventarrayOnLoadCalled == 1) {
|
||||
netty_kqueue_eventarray_JNI_OnUnLoad(env);
|
||||
netty_kqueue_eventarray_JNI_OnUnLoad(env, packagePrefix);
|
||||
}
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
static void netty_kqueue_native_JNI_OnUnLoad(JNIEnv* env) {
|
||||
netty_unix_limits_JNI_OnUnLoad(env);
|
||||
netty_unix_errors_JNI_OnUnLoad(env);
|
||||
netty_unix_filedescriptor_JNI_OnUnLoad(env);
|
||||
netty_unix_socket_JNI_OnUnLoad(env);
|
||||
netty_unix_buffer_JNI_OnUnLoad(env);
|
||||
netty_kqueue_bsdsocket_JNI_OnUnLoad(env);
|
||||
netty_kqueue_eventarray_JNI_OnUnLoad(env);
|
||||
static void netty_kqueue_native_JNI_OnUnLoad(JNIEnv* env, const char* staticPackagePrefix) {
|
||||
netty_unix_limits_JNI_OnUnLoad(env, staticPackagePrefix);
|
||||
netty_unix_errors_JNI_OnUnLoad(env, staticPackagePrefix);
|
||||
netty_unix_filedescriptor_JNI_OnUnLoad(env, staticPackagePrefix);
|
||||
netty_unix_socket_JNI_OnUnLoad(env, staticPackagePrefix);
|
||||
netty_unix_buffer_JNI_OnUnLoad(env, staticPackagePrefix);
|
||||
netty_kqueue_bsdsocket_JNI_OnUnLoad(env, staticPackagePrefix);
|
||||
netty_kqueue_eventarray_JNI_OnUnLoad(env, staticPackagePrefix);
|
||||
}
|
||||
|
||||
static jint JNI_OnLoad_netty_transport_native_kqueue0(JavaVM* vm, void* reserved) {
|
||||
@ -387,9 +404,12 @@ static jint JNI_OnLoad_netty_transport_native_kqueue0(JavaVM* vm, void* reserved
|
||||
}
|
||||
#endif /* NETTY_BUILD_STATIC */
|
||||
jint ret = netty_kqueue_native_JNI_OnLoad(env, packagePrefix);
|
||||
|
||||
// It's safe to call free(...) with a NULL argument as well.
|
||||
free(packagePrefix);
|
||||
if (ret == JNI_ERR) {
|
||||
free(packagePrefix);
|
||||
staticPackagePrefix = NULL;
|
||||
} else {
|
||||
staticPackagePrefix = packagePrefix;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -400,7 +420,9 @@ static void JNI_OnUnload_netty_transport_native_kqueue0(JavaVM* vm, void* reserv
|
||||
// Something is wrong but nothing we can do about this :(
|
||||
return;
|
||||
}
|
||||
netty_kqueue_native_JNI_OnUnLoad(env);
|
||||
netty_kqueue_native_JNI_OnUnLoad(env, staticPackagePrefix);
|
||||
free(staticPackagePrefix);
|
||||
staticPackagePrefix = NULL;
|
||||
}
|
||||
|
||||
// We build with -fvisibility=hidden so ensure we mark everything that needs to be visible with JNIEXPORT
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include "netty_unix_util.h"
|
||||
#include "netty_unix_buffer.h"
|
||||
|
||||
#define BUFFER_CLASSNAME "io/netty/channel/unix/Buffer"
|
||||
|
||||
// JNI Registered Methods Begin
|
||||
static jlong netty_unix_buffer_memoryAddress0(JNIEnv* env, jclass clazz, jobject buffer) {
|
||||
return (jlong) (*env)->GetDirectBufferAddress(env, buffer);
|
||||
@ -40,7 +42,7 @@ jint netty_unix_buffer_JNI_OnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
// We must register the statically referenced methods first!
|
||||
if (netty_unix_util_register_natives(env,
|
||||
packagePrefix,
|
||||
"io/netty/channel/unix/Buffer",
|
||||
BUFFER_CLASSNAME,
|
||||
statically_referenced_fixed_method_table,
|
||||
statically_referenced_fixed_method_table_size) != 0) {
|
||||
return JNI_ERR;
|
||||
@ -49,4 +51,6 @@ jint netty_unix_buffer_JNI_OnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
return NETTY_JNI_VERSION;
|
||||
}
|
||||
|
||||
void netty_unix_buffer_JNI_OnUnLoad(JNIEnv* env) { }
|
||||
void netty_unix_buffer_JNI_OnUnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
netty_unix_util_unregister_natives(env, packagePrefix, BUFFER_CLASSNAME);
|
||||
}
|
||||
|
@ -20,6 +20,6 @@
|
||||
|
||||
// JNI initialization hooks. Users of this file are responsible for calling these in the JNI_OnLoad and JNI_OnUnload methods.
|
||||
jint netty_unix_buffer_JNI_OnLoad(JNIEnv* env, const char* packagePrefix);
|
||||
void netty_unix_buffer_JNI_OnUnLoad(JNIEnv* env);
|
||||
void netty_unix_buffer_JNI_OnUnLoad(JNIEnv* env, const char* packagePrefix);
|
||||
|
||||
#endif /* NETTY_UNIX_BUFFER_H_ */
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "netty_unix_jni.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
#define ERRORS_CLASSNAME "io/netty/channel/unix/ErrorsStaticallyReferencedJniMethods"
|
||||
|
||||
static jclass oomErrorClass = NULL;
|
||||
static jclass runtimeExceptionClass = NULL;
|
||||
static jclass channelExceptionClass = NULL;
|
||||
@ -214,7 +216,7 @@ jint netty_unix_errors_JNI_OnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
// We must register the statically referenced methods first!
|
||||
if (netty_unix_util_register_natives(env,
|
||||
packagePrefix,
|
||||
"io/netty/channel/unix/ErrorsStaticallyReferencedJniMethods",
|
||||
ERRORS_CLASSNAME,
|
||||
statically_referenced_fixed_method_table,
|
||||
statically_referenced_fixed_method_table_size) != 0) {
|
||||
return JNI_ERR;
|
||||
@ -241,7 +243,7 @@ error:
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
void netty_unix_errors_JNI_OnUnLoad(JNIEnv* env) {
|
||||
void netty_unix_errors_JNI_OnUnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
// delete global references so the GC can collect them
|
||||
NETTY_UNLOAD_CLASS(env, oomErrorClass);
|
||||
NETTY_UNLOAD_CLASS(env, runtimeExceptionClass);
|
||||
@ -249,4 +251,6 @@ void netty_unix_errors_JNI_OnUnLoad(JNIEnv* env) {
|
||||
NETTY_UNLOAD_CLASS(env, ioExceptionClass);
|
||||
NETTY_UNLOAD_CLASS(env, portUnreachableExceptionClass);
|
||||
NETTY_UNLOAD_CLASS(env, closedChannelExceptionClass);
|
||||
|
||||
netty_unix_util_unregister_natives(env, packagePrefix, ERRORS_CLASSNAME);
|
||||
}
|
||||
|
@ -29,6 +29,6 @@ void netty_unix_errors_throwOutOfMemoryError(JNIEnv* env);
|
||||
|
||||
// JNI initialization hooks. Users of this file are responsible for calling these in the JNI_OnLoad and JNI_OnUnload methods.
|
||||
jint netty_unix_errors_JNI_OnLoad(JNIEnv* env, const char* packagePrefix);
|
||||
void netty_unix_errors_JNI_OnUnLoad(JNIEnv* env);
|
||||
void netty_unix_errors_JNI_OnUnLoad(JNIEnv* env, const char* packagePrefix);
|
||||
|
||||
#endif /* NETTY_UNIX_ERRORS_H_ */
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "netty_unix_jni.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
#define FILEDESCRIPTOR_CLASSNAME "io/netty/channel/unix/FileDescriptor"
|
||||
|
||||
static jmethodID posId = NULL;
|
||||
static jmethodID limitId = NULL;
|
||||
static jfieldID posFieldId = NULL;
|
||||
@ -278,7 +280,7 @@ static const jint method_table_size = sizeof(method_table) / sizeof(method_table
|
||||
jint netty_unix_filedescriptor_JNI_OnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
int ret = JNI_ERR;
|
||||
void* mem = NULL;
|
||||
if (netty_unix_util_register_natives(env, packagePrefix, "io/netty/channel/unix/FileDescriptor", method_table, method_table_size) != 0) {
|
||||
if (netty_unix_util_register_natives(env, packagePrefix, FILEDESCRIPTOR_CLASSNAME, method_table, method_table_size) != 0) {
|
||||
goto done;
|
||||
}
|
||||
if ((mem = malloc(1)) == NULL) {
|
||||
@ -313,4 +315,6 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void netty_unix_filedescriptor_JNI_OnUnLoad(JNIEnv* env) { }
|
||||
void netty_unix_filedescriptor_JNI_OnUnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
netty_unix_util_unregister_natives(env, packagePrefix, FILEDESCRIPTOR_CLASSNAME);
|
||||
}
|
||||
|
@ -20,6 +20,6 @@
|
||||
|
||||
// JNI initialization hooks. Users of this file are responsible for calling these in the JNI_OnLoad and JNI_OnUnload methods.
|
||||
jint netty_unix_filedescriptor_JNI_OnLoad(JNIEnv* env, const char* packagePrefix);
|
||||
void netty_unix_filedescriptor_JNI_OnUnLoad(JNIEnv* env);
|
||||
void netty_unix_filedescriptor_JNI_OnUnLoad(JNIEnv* env, const char* packagePrefix);
|
||||
|
||||
#endif /* NETTY_UNIX_FILEDESCRIPTOR_H_ */
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "netty_unix_limits.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
#define LIMITS_CLASSNAME "io/netty/channel/unix/LimitsStaticallyReferencedJniMethods"
|
||||
|
||||
// Define IOV_MAX if not found to limit the iov size on writev calls
|
||||
// See https://github.com/netty/netty/issues/2647
|
||||
#ifndef IOV_MAX
|
||||
@ -70,7 +72,7 @@ jint netty_unix_limits_JNI_OnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
// We must register the statically referenced methods first!
|
||||
if (netty_unix_util_register_natives(env,
|
||||
packagePrefix,
|
||||
"io/netty/channel/unix/LimitsStaticallyReferencedJniMethods",
|
||||
LIMITS_CLASSNAME,
|
||||
statically_referenced_fixed_method_table,
|
||||
statically_referenced_fixed_method_table_size) != 0) {
|
||||
return JNI_ERR;
|
||||
@ -79,4 +81,6 @@ jint netty_unix_limits_JNI_OnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
return NETTY_JNI_VERSION;
|
||||
}
|
||||
|
||||
void netty_unix_limits_JNI_OnUnLoad(JNIEnv* env) { }
|
||||
void netty_unix_limits_JNI_OnUnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
netty_unix_util_unregister_natives(env, packagePrefix, LIMITS_CLASSNAME);
|
||||
}
|
||||
|
@ -20,6 +20,6 @@
|
||||
|
||||
// JNI initialization hooks. Users of this file are responsible for calling these in the JNI_OnLoad and JNI_OnUnload methods.
|
||||
jint netty_unix_limits_JNI_OnLoad(JNIEnv* env, const char* packagePrefix);
|
||||
void netty_unix_limits_JNI_OnUnLoad(JNIEnv* env);
|
||||
void netty_unix_limits_JNI_OnUnLoad(JNIEnv* env, const char* packagePrefix);
|
||||
|
||||
#endif /* NETTY_UNIX_LIMITS_H_ */
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "netty_unix_socket.h"
|
||||
#include "netty_unix_util.h"
|
||||
|
||||
#define SOCKET_CLASSNAME "io/netty/channel/unix/Socket"
|
||||
// Define SO_REUSEPORT if not found to fix build issues.
|
||||
// See https://github.com/netty/netty/issues/2558
|
||||
#ifndef SO_REUSEPORT
|
||||
@ -1061,7 +1062,7 @@ jint netty_unix_socket_JNI_OnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
}
|
||||
if (netty_unix_util_register_natives(env,
|
||||
packagePrefix,
|
||||
"io/netty/channel/unix/Socket",
|
||||
SOCKET_CLASSNAME,
|
||||
dynamicMethods,
|
||||
dynamicMethodsTableSize()) != 0) {
|
||||
goto done;
|
||||
@ -1099,7 +1100,9 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void netty_unix_socket_JNI_OnUnLoad(JNIEnv* env) {
|
||||
void netty_unix_socket_JNI_OnUnLoad(JNIEnv* env, const char* packagePrefix) {
|
||||
NETTY_UNLOAD_CLASS(env, datagramSocketAddressClass);
|
||||
NETTY_UNLOAD_CLASS(env, inetSocketAddressClass);
|
||||
|
||||
netty_unix_util_unregister_natives(env, packagePrefix, SOCKET_CLASSNAME);
|
||||
}
|
||||
|
@ -34,6 +34,6 @@ void netty_unix_socket_getOptionHandleError(JNIEnv* env, int err);
|
||||
|
||||
// JNI initialization hooks. Users of this file are responsible for calling these in the JNI_OnLoad and JNI_OnUnload methods.
|
||||
jint netty_unix_socket_JNI_OnLoad(JNIEnv* env, const char* packagePrefix);
|
||||
void netty_unix_socket_JNI_OnUnLoad(JNIEnv* env);
|
||||
void netty_unix_socket_JNI_OnUnLoad(JNIEnv* env, const char* packagePrefix);
|
||||
|
||||
#endif /* NETTY_UNIX_SOCKET_H_ */
|
||||
|
@ -223,6 +223,22 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
jint netty_unix_util_unregister_natives(JNIEnv* env, const char* packagePrefix, const char* className) {
|
||||
char* nettyClassName = NULL;
|
||||
int ret = JNI_ERR;
|
||||
NETTY_PREPEND(packagePrefix, className, nettyClassName, done);
|
||||
|
||||
jclass nativeCls = (*env)->FindClass(env, nettyClassName);
|
||||
if (nativeCls == NULL) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = (*env)->UnregisterNatives(env, nativeCls);
|
||||
done:
|
||||
free(nettyClassName);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void netty_unix_util_free_dynamic_methods_table(JNINativeMethod* dynamicMethods, jint fixedMethodTableSize, jint fullMethodTableSize) {
|
||||
if (dynamicMethods != NULL) {
|
||||
jint i = fixedMethodTableSize;
|
||||
|
@ -149,6 +149,7 @@ jboolean netty_unix_util_timespec_subtract_ns(struct timespec* ts, uint64_t nano
|
||||
* Return type is as defined in https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#wp5833.
|
||||
*/
|
||||
jint netty_unix_util_register_natives(JNIEnv* env, const char* packagePrefix, const char* className, const JNINativeMethod* methods, jint numMethods);
|
||||
jint netty_unix_util_unregister_natives(JNIEnv* env, const char* packagePrefix, const char* className);
|
||||
|
||||
void netty_unix_util_free_dynamic_methods_table(JNINativeMethod* dynamicMethods, jint fixedMethodTableSize, jint fullMethodTableSize);
|
||||
void netty_unix_util_free_dynamic_name(char** dynamicName);
|
||||
|
Loading…
Reference in New Issue
Block a user