mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-08-27 08:55:48 +00:00
another series of improvements for the jvm
This commit is contained in:
@@ -41,6 +41,10 @@ struct uwsgi_gateway *register_gateway(char *name, void (*loop) (int, void *), v
|
||||
return ug;
|
||||
}
|
||||
|
||||
static void gateway_brutal_end() {
|
||||
_exit(UWSGI_END_CODE);
|
||||
}
|
||||
|
||||
void gateway_respawn(int id) {
|
||||
|
||||
pid_t gw_pid;
|
||||
@@ -65,6 +69,7 @@ void gateway_respawn(int id) {
|
||||
}
|
||||
#endif
|
||||
uwsgi.mypid = getpid();
|
||||
atexit(gateway_brutal_end);
|
||||
signal(SIGALRM, SIG_IGN);
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
signal(SIGINT, end_me);
|
||||
|
||||
@@ -734,6 +734,7 @@ struct uwsgi_route_condition *uwsgi_register_route_condition(char *name, int (*f
|
||||
|
||||
void uwsgi_routing_dump() {
|
||||
struct uwsgi_route *routes = uwsgi.routes;
|
||||
if (!routes) return;
|
||||
uwsgi_log("*** dumping internal routing table ***\n");
|
||||
while(routes) {
|
||||
if (routes->label) {
|
||||
|
||||
+6
-1
@@ -15,9 +15,13 @@ int uwsgi_register_rpc(char *name, uint8_t modifier1, uint8_t args, void *func)
|
||||
uwsgi_lock(uwsgi.rpc_table_lock);
|
||||
|
||||
if (uwsgi.shared->rpc_count < uwsgi.rpc_max) {
|
||||
uwsgi_log("rpc_max = %d %d\n", uwsgi.rpc_max, uwsgi.shared->rpc_count);
|
||||
urpc = &uwsgi.rpc_table[uwsgi.shared->rpc_count];
|
||||
uwsgi_log("rpc_max = %d\n", uwsgi.rpc_max);
|
||||
|
||||
uwsgi_log("NAME = %s %d %p\n", name, strlen(name), urpc->name);
|
||||
memcpy(urpc->name, name, strlen(name));
|
||||
uwsgi_log("NAME = %s\n", name);
|
||||
urpc->modifier1 = modifier1;
|
||||
urpc->args = args;
|
||||
urpc->func = func;
|
||||
@@ -69,7 +73,7 @@ char *uwsgi_do_rpc(char *node, char *func, uint8_t argc, char *argv[], uint16_t
|
||||
|
||||
if (node == NULL || !strcmp(node, "")) {
|
||||
// allocate the whole buffer
|
||||
buffer = uwsgi_malloc(65536);
|
||||
buffer = uwsgi_malloc(UMAX16);
|
||||
*len = uwsgi_rpc(func, argc, argv, argvs, buffer);
|
||||
return buffer;
|
||||
}
|
||||
@@ -145,5 +149,6 @@ error:
|
||||
|
||||
|
||||
void uwsgi_rpc_init() {
|
||||
uwsgi_log("ALLOCATE\n");
|
||||
uwsgi.rpc_table = uwsgi_calloc_shared(sizeof(struct uwsgi_rpc) * uwsgi.rpc_max);
|
||||
}
|
||||
|
||||
@@ -96,6 +96,8 @@ int uwsgi_register_signal(uint8_t sig, char *receiver, void *handler, uint8_t mo
|
||||
|
||||
struct uwsgi_signal_entry *use = NULL;
|
||||
|
||||
if (!uwsgi.master_process) return -1;
|
||||
|
||||
if (strlen(receiver) > 63)
|
||||
return -1;
|
||||
|
||||
|
||||
+3
-3
@@ -2167,6 +2167,9 @@ int uwsgi_start(void *v_argv) {
|
||||
// setup locking
|
||||
uwsgi_setup_locking();
|
||||
|
||||
// allocate rpc structures
|
||||
uwsgi_rpc_init();
|
||||
|
||||
// setup sharedarea
|
||||
if (uwsgi.sharedareasize > 0) {
|
||||
uwsgi.sharedarea = uwsgi_calloc_shared(uwsgi.page_size * uwsgi.sharedareasize);
|
||||
@@ -2393,9 +2396,6 @@ unsafe:
|
||||
}
|
||||
}
|
||||
|
||||
// allocate rpc structures
|
||||
uwsgi_rpc_init();
|
||||
|
||||
// set masterpid
|
||||
uwsgi.mypid = getpid();
|
||||
masterpid = uwsgi.mypid;
|
||||
|
||||
+12
-1
@@ -11,12 +11,23 @@ struct uwsgi_jvm {
|
||||
struct uwsgi_string_list *main_classes;
|
||||
|
||||
jclass str_class;
|
||||
jclass runtime_exception;
|
||||
|
||||
jmethodID api_signal_handler_mid;
|
||||
jmethodID api_rpc_function_mid;
|
||||
};
|
||||
|
||||
|
||||
jclass uwsgi_jvm_class(char *);
|
||||
jobject uwsgi_jvm_ref(jobject);
|
||||
void uwsgi_jvm_unref(jobject);
|
||||
int uwsgi_jvm_call_static(jclass, jmethodID);
|
||||
int uwsgi_jvm_call_static(jclass, jmethodID, ...);
|
||||
int uwsgi_jvm_call(jobject, jmethodID, ...);
|
||||
|
||||
void uwsgi_jvm_clear_exception(void);
|
||||
char *uwsgi_jvm_str2c(jobject);
|
||||
|
||||
void uwsgi_jvm_throw(char *);
|
||||
|
||||
jobject uwsgi_jvm_call_objectA(jobject o, jmethodID mid, jvalue *);
|
||||
void uwsgi_jvm_release_chars(jobject, char *);
|
||||
|
||||
+105
-24
@@ -10,18 +10,30 @@ This plugin is the core for all of the JVM-based ones
|
||||
*/
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
struct uwsgi_plugin jvm_plugin;
|
||||
|
||||
JNIEXPORT jint JNICALL uwsgi_jvm_api_worker_id(JNIEnv *env) {
|
||||
JNIEXPORT jint JNICALL uwsgi_jvm_api_worker_id(JNIEnv *env, jclass c) {
|
||||
return uwsgi.mywid;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL uwsgi_jvm_api_hello(JNIEnv *env, jclass c) {
|
||||
uwsgi_log("AAAA\n");
|
||||
JNIEXPORT void JNICALL uwsgi_jvm_api_register_signal(JNIEnv *env, jclass c, jint signum, jstring target, jobject handler) {
|
||||
char *t = uwsgi_jvm_str2c(target);
|
||||
if (uwsgi_register_signal(signum, t, uwsgi_jvm_ref(handler), jvm_plugin.modifier1)) {
|
||||
uwsgi_jvm_throw("unable to register signal handler");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL uwsgi_jvm_api_register_rpc(JNIEnv *env, jclass c, jstring name, jobject func) {
|
||||
char *n = uwsgi_jvm_str2c(name);
|
||||
if (uwsgi_register_rpc(n, jvm_plugin.modifier1, 0, uwsgi_jvm_ref(func))) {
|
||||
uwsgi_jvm_throw("unable to register rpc function");
|
||||
}
|
||||
}
|
||||
|
||||
static JNINativeMethod uwsgi_jvm_api_methods[] = {
|
||||
{"register_signal", "(ILjava/lang/String;Luwsgi$SignalHandler;)V", (void *) &uwsgi_jvm_api_register_signal},
|
||||
{"register_rpc", "(Ljava/lang/String;Luwsgi$RpcFunction;)V", (void *) &uwsgi_jvm_api_register_rpc},
|
||||
{"worker_id", "()I", (void *) &uwsgi_jvm_api_worker_id},
|
||||
{"hello", "()V", (void *) &uwsgi_jvm_api_hello},
|
||||
};
|
||||
|
||||
struct uwsgi_jvm ujvm;
|
||||
@@ -59,6 +71,7 @@ jclass uwsgi_jvm_class(char *name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return my_class;
|
||||
return uwsgi_jvm_ref(my_class);
|
||||
}
|
||||
|
||||
@@ -73,7 +86,7 @@ jmethodID uwsgi_jvm_get_static_method_id(jclass cls, char *name, char *signature
|
||||
}
|
||||
|
||||
jobject uwsgi_jvm_ref(jobject obj) {
|
||||
return (*ujvm.env)->NewLocalRef(ujvm.env, obj);
|
||||
return (*ujvm.env)->NewGlobalRef(ujvm.env, obj);
|
||||
}
|
||||
|
||||
void uwsgi_jvm_unref(jobject obj) {
|
||||
@@ -91,14 +104,37 @@ jobject uwsgi_jvm_str(char *str, size_t len) {
|
||||
new_str = (*ujvm.env)->NewStringUTF(ujvm.env, str);
|
||||
}
|
||||
|
||||
return uwsgi_jvm_ref(new_str);
|
||||
return new_str;
|
||||
}
|
||||
|
||||
int uwsgi_jvm_call_static(jclass c, jmethodID mid) {
|
||||
(*ujvm.env)->CallStaticVoidMethod(ujvm.env, c, mid);
|
||||
int uwsgi_jvm_call_static(jclass c, jmethodID mid, ...) {
|
||||
va_list args;
|
||||
va_start(args, mid);
|
||||
(*ujvm.env)->CallStaticVoidMethod(ujvm.env, c, mid, args);
|
||||
va_end(args);
|
||||
return uwsgi_jvm_exception();
|
||||
}
|
||||
|
||||
int uwsgi_jvm_call(jobject o, jmethodID mid, ...) {
|
||||
va_list args;
|
||||
va_start(args, mid);
|
||||
(*ujvm.env)->CallVoidMethodV(ujvm.env, o, mid, args);
|
||||
va_end(args);
|
||||
return uwsgi_jvm_exception();
|
||||
}
|
||||
|
||||
jobject uwsgi_jvm_call_objectA(jobject o, jmethodID mid, jvalue *args) {
|
||||
jobject ret = (*ujvm.env)->CallObjectMethodA(ujvm.env, o, mid, args);
|
||||
if (uwsgi_jvm_exception()) {
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void uwsgi_jvm_throw(char *message) {
|
||||
(*ujvm.env)->ThrowNew(ujvm.env, ujvm.runtime_exception, message);
|
||||
}
|
||||
|
||||
static int uwsgi_jvm_init(void) {
|
||||
|
||||
JavaVM *jvm;
|
||||
@@ -146,6 +182,12 @@ static int uwsgi_jvm_init(void) {
|
||||
uwsgi_log("JVM initialized at %p\n", ujvm.env);
|
||||
}
|
||||
|
||||
ujvm.str_class = uwsgi_jvm_class("java/lang/String");
|
||||
if (!ujvm.str_class) exit(1);
|
||||
|
||||
ujvm.runtime_exception = uwsgi_jvm_class("java/lang/RuntimeException");
|
||||
if (!ujvm.runtime_exception) exit(1);
|
||||
|
||||
jclass uwsgi_class = uwsgi_jvm_class("uwsgi");
|
||||
if (!uwsgi_class) {
|
||||
exit(1);
|
||||
@@ -155,6 +197,16 @@ static int uwsgi_jvm_init(void) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
jclass uwsgi_signal_handler_class = uwsgi_jvm_class("uwsgi$SignalHandler");
|
||||
if (!uwsgi_signal_handler_class) exit(1);
|
||||
ujvm.api_signal_handler_mid = uwsgi_jvm_get_method_id(uwsgi_signal_handler_class, "function", "(I)V");
|
||||
if (!ujvm.api_signal_handler_mid) exit(1);
|
||||
|
||||
jclass uwsgi_rpc_function_class = uwsgi_jvm_class("uwsgi$RpcFunction");
|
||||
if (!uwsgi_rpc_function_class) exit(1);
|
||||
ujvm.api_rpc_function_mid = uwsgi_jvm_get_method_id(uwsgi_rpc_function_class, "function", "([Ljava/lang/String;)Ljava/lang/String;");
|
||||
if (!ujvm.api_rpc_function_mid) exit(1);
|
||||
|
||||
struct uwsgi_string_list *usl = ujvm.main_classes;
|
||||
while(usl) {
|
||||
jclass c = uwsgi_jvm_class(usl->value);
|
||||
@@ -175,23 +227,7 @@ static int uwsgi_jvm_init(void) {
|
||||
}
|
||||
usl = usl->next;
|
||||
}
|
||||
/*
|
||||
if (ujvm.class) {
|
||||
ujvm.main_class = uwsgi_jvm_get_class(ujvm.class);
|
||||
if (!ujvm.main_class) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
mmid = uwsgi_jvm_get_static_method_id(ujvm.main_class, "main", "([Ljava/lang/String;)V");
|
||||
if (mmid) {
|
||||
(*ujvm.env)->CallStaticVoidMethod(ujvm.env, ujvm.main_class, mmid);
|
||||
uwsgi_jvm_exception();
|
||||
}
|
||||
}
|
||||
|
||||
ujvm.str_class = uwsgi_jvm_get_class("java/lang/String");
|
||||
ujvm.ht_class = uwsgi_jvm_get_class("java/util/Hashtable");
|
||||
*/
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -207,10 +243,55 @@ size_t uwsgi_jvm_strlen(jobject obj) {
|
||||
return (*ujvm.env)->GetStringUTFLength(ujvm.env, obj);
|
||||
}
|
||||
|
||||
static int uwsgi_jvm_signal_handler(uint8_t signum, void *handler) {
|
||||
long l_signum = signum;
|
||||
return uwsgi_jvm_call(handler, ujvm.api_signal_handler_mid, (void *) l_signum);
|
||||
}
|
||||
|
||||
// route request to the specific JVM plugin (identified by modifier2)
|
||||
static int uwsgi_jvm_request(struct wsgi_request *wsgi_req) {
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
void uwsgi_jvm_release_chars(jobject o, char *str) {
|
||||
(*ujvm.env)->ReleaseStringUTFChars(ujvm.env, o, str);
|
||||
}
|
||||
|
||||
static uint16_t uwsgi_jvm_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[], char *buffer) {
|
||||
jvalue *args = uwsgi_calloc(sizeof(jvalue) * argc+1);
|
||||
uint8_t i;
|
||||
for(i=0;i<argc;i++) {
|
||||
args[i] = (jvalue) uwsgi_jvm_str(argv[i], argvs[i]);
|
||||
}
|
||||
jobject ret = uwsgi_jvm_call_objectA(func, ujvm.api_rpc_function_mid, args);
|
||||
free(args);
|
||||
if (ret == NULL) {
|
||||
goto end;
|
||||
}
|
||||
size_t rlen = uwsgi_jvm_strlen(ret);
|
||||
if (rlen <= 0xffff) {
|
||||
char *b = uwsgi_jvm_str2c(ret);
|
||||
memcpy(buffer, b, rlen);
|
||||
uwsgi_jvm_release_chars(ret, b);
|
||||
(*ujvm.env)->DeleteLocalRef(ujvm.env, ret);
|
||||
return rlen;
|
||||
}
|
||||
end:
|
||||
(*ujvm.env)->DeleteLocalRef(ujvm.env, ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct uwsgi_plugin jvm_plugin = {
|
||||
.name = "jvm",
|
||||
.modifier1 = 8,
|
||||
|
||||
.request = uwsgi_jvm_request,
|
||||
|
||||
.init = uwsgi_jvm_init,
|
||||
.options = uwsgi_jvm_options,
|
||||
|
||||
.signal_handler = uwsgi_jvm_signal_handler,
|
||||
.rpc = uwsgi_jvm_rpc,
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -540,7 +540,7 @@ static void uwsgi_mono_enable_threads(void) {
|
||||
|
||||
static void uwsgi_mono_post_fork() {
|
||||
|
||||
// yes, ono is not fork-friendly, so we initialize it in the post_fork hook
|
||||
// yes, Mono is not fork-friendly, so we initialize it in the post_fork hook
|
||||
uwsgi_mono_init_apps();
|
||||
|
||||
MonoMethodDesc *desc = mono_method_desc_new("uwsgi.api:RunPostForkHook()", 1);
|
||||
|
||||
+10
-22
@@ -1,16 +1,18 @@
|
||||
#include "../../uwsgi.h"
|
||||
#include <uwsgi.h>
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
|
||||
int uwsgi_rpc_request(struct wsgi_request *wsgi_req) {
|
||||
static int uwsgi_rpc_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
// this is the list of args
|
||||
char *argv[256];
|
||||
char *argv[UMAX8];
|
||||
// this is the size of each argument
|
||||
uint16_t argvs[256];
|
||||
uint16_t argvs[UMAX8];
|
||||
// maximum number of supported arguments
|
||||
uint8_t argc = 0xff;
|
||||
// response output
|
||||
char response_buf[UMAX16];
|
||||
|
||||
/* Standard RPC request */
|
||||
if (!wsgi_req->uh->pktsize) {
|
||||
@@ -18,38 +20,24 @@ int uwsgi_rpc_request(struct wsgi_request *wsgi_req) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
for(argc=0;argc<wsgi_req->uh.pktsize;argc++) {
|
||||
uwsgi_log("rpc: %c\n", wsgi_req->buffer[argc]);
|
||||
}
|
||||
*/
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("RPC pktsize %d\n", wsgi_req->uh->pktsize);
|
||||
#endif
|
||||
|
||||
if (uwsgi_parse_array(wsgi_req->buffer, wsgi_req->uh->pktsize, argv, argvs, &argc)) {
|
||||
uwsgi_log("Invalid RPC request. skip.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("RPC args %d\n", argc-1);
|
||||
#endif
|
||||
|
||||
// call the function (output will be in wsgi_req->buffer)
|
||||
wsgi_req->uh->pktsize = uwsgi_rpc(argv[0], argc-1, argv+1, argvs+1, wsgi_req->buffer);
|
||||
wsgi_req->uh->pktsize = uwsgi_rpc(argv[0], argc-1, argv+1, argvs+1, response_buf);
|
||||
|
||||
// using modifier1 we may want a raw output
|
||||
// using modifier2 we may want a raw output
|
||||
if (wsgi_req->uh->modifier2 == 0) {
|
||||
if (uwsgi_response_write_body_do(wsgi_req, (char *) wsgi_req->uh, 4)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// write the response
|
||||
uwsgi_response_write_body_do(wsgi_req, wsgi_req->buffer, wsgi_req->uh->pktsize);
|
||||
uwsgi_response_write_body_do(wsgi_req, response_buf, wsgi_req->uh->pktsize);
|
||||
|
||||
return 0;
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
struct uwsgi_plugin rpc_plugin = {
|
||||
|
||||
Reference in New Issue
Block a user