another series of improvements for the jvm

This commit is contained in:
Unbit
2013-03-03 12:36:35 +01:00
parent 1e6dd22fd8
commit 92e06b1078
10 changed files with 147 additions and 53 deletions
+5
View File
@@ -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);
+1
View File
@@ -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
View File
@@ -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);
}
+2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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,
};
+1 -1
View File
@@ -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
View File
@@ -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 = {
+2 -1
View File
@@ -7,6 +7,7 @@ extern "C" {
#endif
#define UMAX16 65536
#define UMAX8 256
#define UMAX64_STR "18446744073709551616"
@@ -2239,7 +2240,7 @@ struct uwsgi_server {
};
struct uwsgi_rpc {
char name[0xff];
char name[UMAX8];
void *func;
uint8_t args;
uint8_t modifier1;