Skip to content

Commit 6506c0f

Browse files
committed
add some memory release methods to prepare for embedding APIs nginx-clojure#86
1 parent 3a1e2cf commit 6506c0f

8 files changed

+150
-25
lines changed

src/c/ngx_http_clojure_jvm.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@
1515

1616
static JNIEnv *jvm_env = NULL;
1717
static JavaVM *jvm = NULL;
18-
static jclass Class_java_lang_String = NULL;
19-
static jmethodID MID_String_init = NULL;
20-
static jmethodID MID_String_getBytes = NULL;
18+
19+
int ngx_http_clojure_is_embeded_by_jse = 0;
2120

2221
int ngx_http_clojure_check_jvm() {
2322
return jvm == NULL ? NGX_HTTP_CLOJURE_JVM_ERR : NGX_HTTP_CLOJURE_JVM_OK;
@@ -98,15 +97,15 @@ int ngx_http_clojure_init_jvm(char *jvm_path, char * *opts, size_t len) {
9897

9998
free(options);
10099
jvm_env = env;
101-
Class_java_lang_String = (*jvm_env)->FindClass(jvm_env, "java/lang/String");
102-
MID_String_getBytes = (*jvm_env)->GetMethodID(jvm_env, Class_java_lang_String, "getBytes", "()[B");
103-
MID_String_init = (*jvm_env)->GetMethodID(jvm_env, Class_java_lang_String, "<init>", "([B)V");
104-
105100

106101
return NGX_HTTP_CLOJURE_JVM_OK;
107-
108102
}
109103

104+
int ngx_http_clojure_init_by_jse_app(JNIEnv *env) {
105+
ngx_http_clojure_is_embeded_by_jse = 1;
106+
jvm_env = env;
107+
return (*env)->GetJavaVM(env, &jvm);
108+
}
110109

111110

112111
int ngx_http_clojure_close_jvm() {
@@ -117,6 +116,13 @@ int ngx_http_clojure_close_jvm() {
117116
return NGX_HTTP_CLOJURE_JVM_OK;
118117
}
119118

119+
if (ngx_http_clojure_is_embeded_by_jse) {
120+
jvm = NULL;
121+
jvm_env = NULL;
122+
ngx_http_clojure_is_embeded_by_jse = 0;
123+
return NGX_HTTP_CLOJURE_JVM_OK;
124+
}
125+
120126
systemClass = (*jvm_env)->FindClass(jvm_env, "java/lang/System");
121127
exitMethod = (*jvm_env)->GetStaticMethodID(jvm_env, systemClass, "exit", "(I)V");
122128
(*jvm_env)->CallStaticVoidMethod(jvm_env, systemClass, exitMethod, 0);

src/c/ngx_http_clojure_jvm.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ typedef jint (*jni_createvm_pt)(JavaVM **pvm, void **penv, void *args);
9090
#define ngx_http_clojure_abs_addr(jobj) \
9191
(jobj ? (void *)((char *)(*(uintptr_t*)jobj)) : (void *)(uintptr_t)0;
9292

93+
extern int ngx_http_clojure_is_embeded_by_jse;
94+
9395
int ngx_http_clojure_check_jvm();
9496

9597
/*
@@ -98,6 +100,8 @@ int ngx_http_clojure_check_jvm();
98100
*/
99101
int ngx_http_clojure_init_jvm(char *jvm_path, char * *opts, size_t len);
100102

103+
int ngx_http_clojure_init_by_jse_app(JNIEnv *env);
104+
101105
int ngx_http_clojure_get_env(JNIEnv **penv);
102106

103107
int ngx_http_clojure_get_jvm(JavaVM **pvm);

src/c/ngx_http_clojure_mem.c

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ static JavaVM *jvm = NULL;
1515
static JNIEnv *jvm_env = NULL;
1616
static jclass nc_rt_class;
1717
static jmethodID nc_rt_eval_mid;
18+
static jmethodID nc_rt_destory_mid;
1819
static jmethodID nc_rt_register_code_mid;
1920
static jmethodID nc_rt_handle_post_event_mid;
2021
static jmethodID nc_rt_handle_channel_event_mid;
@@ -3272,12 +3273,12 @@ static int ngx_http_clojure_pipe(ngx_socket_t fds[2]) {
32723273
return -1;
32733274
}
32743275
#endif
3275-
if (ngx_nonblocking(nc_jvm_worker_pipe_fds[0]) == -1) {
3276+
if (ngx_nonblocking(fds[0]) == -1) {
32763277
ngx_log_error(NGX_LOG_ERR, ngx_http_clojure_global_cycle->log, errno, "ngx clojure create worker_pipe at ngx_nonblocking(fds[0]) failed");
32773278
return -1;
32783279
}
32793280

3280-
if (ngx_nonblocking(nc_jvm_worker_pipe_fds[1]) == -1) {
3281+
if (ngx_nonblocking(fds[1]) == -1) {
32813282
ngx_log_error(NGX_LOG_ERR, ngx_http_clojure_global_cycle->log, errno, "ngx clojure: create worker_pipe at ngx_nonblocking(fds[1]) failed");
32823283
return -1;
32833284
}
@@ -3340,7 +3341,7 @@ static int ngx_http_clojure_pipe_close(ngx_socket_t fd) {
33403341

33413342
}
33423343

3343-
static ngx_int_t ngx_http_clojure_post_event(ngx_socket_t fd, void *e, size_t size) {
3344+
ngx_int_t ngx_http_clojure_post_event(ngx_socket_t fd, void *e, size_t size) {
33443345
/*TODO: handle EGAIN*/
33453346
ngx_int_t wc;
33463347
#if !(NGX_WIN32)
@@ -3392,9 +3393,8 @@ static ngx_int_t ngx_http_clojure_broadcast_event(void *e, size_t size, int has_
33923393
#endif
33933394
}
33943395

3395-
#define ngx_http_clojure_mem_complex_event_buf_helper(buf, e, data, off, len) \
3396+
#define ngx_http_clojure_mem_complex_event_buf_helper(buf, e, src, len) \
33963397
do { \
3397-
char *src = ngx_http_clojure_abs_off_addr(data, off); \
33983398
len = (int)(0xffffLL & e); \
33993399
if (len > (int)sizeof(buf) - 8) { \
34003400
len = sizeof(buf) - 8; \
@@ -3405,6 +3405,14 @@ static ngx_int_t ngx_http_clojure_broadcast_event(void *e, size_t size, int has_
34053405
memcpy(buf + 8, src, len); \
34063406
}while(0)
34073407

3408+
ngx_int_t ngx_http_clojure_mem_wakeup_event_loop() {
3409+
jlong e = 0;
3410+
if (nc_jvm_worker_pipe_fds[1]) {
3411+
return ngx_http_clojure_post_event(nc_jvm_worker_pipe_fds[1], &e, 8);
3412+
}
3413+
return 1;
3414+
}
3415+
34083416
static jlong JNICALL jni_ngx_http_clojure_mem_post_event(JNIEnv *env, jclass cls, jlong e, jobject data, jlong off) {
34093417
/*sizeof(jlong) is zero on win32 vc2010, so we have to use const 8*/
34103418
int rc;
@@ -3415,7 +3423,7 @@ static jlong JNICALL jni_ngx_http_clojure_mem_post_event(JNIEnv *env, jclass cls
34153423
char buf[4096];
34163424
#endif
34173425
int len;
3418-
ngx_http_clojure_mem_complex_event_buf_helper(buf, e, data, off, len);
3426+
ngx_http_clojure_mem_complex_event_buf_helper(buf, e, ngx_http_clojure_abs_off_addr(data, off), len);
34193427
rc = ngx_http_clojure_post_event(nc_jvm_worker_pipe_fds[1], buf, len + 8);
34203428
log_debug2(ngx_http_clojure_global_cycle->log, "ngx clojure: ngx clojure post event %" PRIu64 ", rc:%d", e, rc);
34213429
}else {
@@ -3436,7 +3444,7 @@ static jlong JNICALL jni_ngx_http_clojure_mem_broadcast_event(JNIEnv *env, jclas
34363444
char buf[4096];
34373445
#endif
34383446
int len;
3439-
ngx_http_clojure_mem_complex_event_buf_helper(buf, e, data, off, len);
3447+
ngx_http_clojure_mem_complex_event_buf_helper(buf, e, ngx_http_clojure_abs_off_addr(data, off), len);
34403448
rc = ngx_http_clojure_broadcast_event(buf, len + 8, (int)has_self);
34413449
log_debug2(ngx_http_clojure_global_cycle->log, "ngx clojure: ngx clojure broadcast event %" PRIu64 ", rc:%d", e, rc);
34423450
}else {
@@ -3557,6 +3565,33 @@ int ngx_http_clojure_pipe_init_by_master(int workers) {
35573565
return NGX_OK;
35583566
}
35593567

3568+
int ngx_http_clojure_pipe_exit_by_master() {
3569+
#if !(NGX_WIN32)
3570+
int s = 0;
3571+
int i = 0;
3572+
for (i = 0; i < nc_ngx_workers; i++) {
3573+
for (; s < ngx_last_process; s++) {
3574+
if (ngx_processes[s].pid == -1) {
3575+
break;
3576+
}
3577+
}
3578+
if (nc_ngx_worker_pipes_fds[s][0]) {
3579+
ngx_http_clojure_pipe_close(nc_ngx_worker_pipes_fds[s][0]);
3580+
ngx_http_clojure_pipe_close(nc_ngx_worker_pipes_fds[s][1]);
3581+
nc_ngx_worker_pipes_fds[s][0] = 0;
3582+
nc_ngx_worker_pipes_fds[s][1] = 0;
3583+
}
3584+
s++;
3585+
}
3586+
#else
3587+
if (nc_jvm_worker_pipe_fds[0]) {
3588+
ngx_http_clojure_pipe_close(nc_jvm_worker_pipe_fds[0]);
3589+
ngx_http_clojure_pipe_close(nc_jvm_worker_pipe_fds[1]);
3590+
}
3591+
#endif
3592+
return NGX_OK;
3593+
}
3594+
35603595
static int ngx_http_clojure_pipe_init_by_worker(ngx_log_t *log) {
35613596
#if !(NGX_WIN32)
35623597
nc_jvm_worker_pipe_fds[0] = nc_ngx_worker_pipes_fds[ngx_process_slot][0];
@@ -3834,6 +3869,9 @@ int ngx_http_clojure_init_memory_util(ngx_http_core_srv_conf_t *cscf, ngx_http_c
38343869
nc_rt_init_mid = (*env)->GetStaticMethodID(env, nc_rt_class,"initMemIndex", "(J)V");
38353870
exception_handle(nc_rt_init_mid == NULL, env, return NGX_HTTP_CLOJURE_JVM_ERR);
38363871

3872+
nc_rt_destory_mid = (*env)->GetStaticMethodID(env, nc_rt_class,"destoryMemIndex", "()V");
3873+
exception_handle(nc_rt_destory_mid == NULL, env, return NGX_HTTP_CLOJURE_JVM_ERR);
3874+
38373875
nc_rt_handle_post_event_mid = (*env)->GetStaticMethodID(env, nc_rt_class,"handlePostEvent", "(JJ)I");
38383876
exception_handle(nc_rt_handle_post_event_mid == NULL, env, return NGX_HTTP_CLOJURE_JVM_ERR);
38393877

@@ -3848,6 +3886,22 @@ int ngx_http_clojure_init_memory_util(ngx_http_core_srv_conf_t *cscf, ngx_http_c
38483886
return ngx_http_clojure_init_memory_util_flag = NGX_HTTP_CLOJURE_JVM_OK;
38493887
}
38503888

3889+
int ngx_http_clojure_destroy_memory_util(ngx_log_t *log) {
3890+
JNIEnv *env;
3891+
ngx_http_clojure_get_env(&jvm_env);
3892+
3893+
if (jvm_env == NULL) {
3894+
return NGX_HTTP_CLOJURE_JVM_ERR_INIT_SOCKETAPI;
3895+
}
3896+
3897+
ngx_http_clojure_init_memory_util_flag = NGX_HTTP_CLOJURE_JVM_ERR;
3898+
3899+
env = jvm_env;
3900+
(*env)->CallStaticVoidMethod(env, nc_rt_class, nc_rt_destory_mid);
3901+
exception_handle(1, env, return NGX_HTTP_CLOJURE_JVM_ERR);
3902+
3903+
return 0;
3904+
}
38513905

38523906

38533907

src/c/ngx_http_clojure_mem.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77

88
#include <nginx.h>
99
#include <ngx_http.h>
10+
#if (NGX_HAVE_SHA1)
1011
#include <ngx_sha1.h>
12+
#endif
1113

1214

1315

@@ -505,12 +507,18 @@ int ngx_http_clojure_check_memory_util();
505507

506508
int ngx_http_clojure_pipe_init_by_master(int workers);
507509

510+
int ngx_http_clojure_pipe_exit_by_master();
511+
512+
ngx_int_t ngx_http_clojure_mem_wakeup_event_loop();
508513

509514
/*
510515
*
511516
*/
512517
int ngx_http_clojure_init_memory_util(ngx_http_core_srv_conf_t *cscf, ngx_http_clojure_main_conf_t *mcf, ngx_log_t *log);
513518

519+
int ngx_http_clojure_destroy_memory_util(ngx_log_t *log);
520+
521+
514522
int ngx_http_clojure_register_script(ngx_int_t phase, ngx_str_t *handler_type,
515523
ngx_str_t *handler, ngx_str_t *code, ngx_array_t *pros, ngx_int_t *pcid);
516524

src/c/ngx_http_clojure_module.c

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ static char* ngx_http_clojure_merge_loc_conf(ngx_conf_t *cf, void *parent, void
4545

4646
static ngx_int_t ngx_http_clojure_module_init(ngx_cycle_t *cycle);
4747

48+
static void ngx_http_clojure_module_exit(ngx_cycle_t *cycle);
49+
4850
static ngx_int_t ngx_http_clojure_process_init(ngx_cycle_t *cycle);
4951

5052
static void ngx_http_clojure_process_exit(ngx_cycle_t *cycle);
@@ -471,7 +473,7 @@ ngx_module_t ngx_http_clojure_module = {
471473
NULL, /* init thread */
472474
NULL, /* exit thread */
473475
ngx_http_clojure_process_exit, /* exit process */
474-
NULL, /* exit master */
476+
ngx_http_clojure_module_exit, /* exit master */
475477
NGX_MODULE_V1_PADDING
476478
};
477479

@@ -517,8 +519,16 @@ static void * ngx_http_clojure_create_main_conf(ngx_conf_t *cf) {
517519
if (conf == NULL) {
518520
return NGX_CONF_ERROR;
519521
}
520-
conf->jvm_path.len = NGX_CONF_UNSET_SIZE;
521-
conf->jvm_options = NGX_CONF_UNSET_PTR;
522+
523+
if (ngx_http_clojure_is_embeded_by_jse) {
524+
conf->jvm_disable_all = 0;
525+
conf->jvm_path.data = (u_char*)"auto";
526+
conf->jvm_path.len = sizeof("auto") - 1;
527+
}else {
528+
conf->jvm_path.len = NGX_CONF_UNSET_SIZE;
529+
conf->jvm_options = NGX_CONF_UNSET_PTR;
530+
}
531+
522532
conf->jvm_workers = NGX_CONF_UNSET;
523533
conf->max_balanced_tcp_connections = NGX_CONF_UNSET;
524534
conf->jvm_init_handler_id = conf->jvm_exit_handler_id = -1;
@@ -843,6 +853,17 @@ static ngx_int_t ngx_http_clojure_module_init(ngx_cycle_t *cycle) {
843853
return NGX_OK;
844854
}
845855

856+
static void ngx_http_clojure_module_exit(ngx_cycle_t *cycle) {
857+
#if !(NGX_WIN32)
858+
ngx_shm_free(&ngx_http_clojure_shared_memory);
859+
#else
860+
ngx_http_clojure_jvm_be_mad_times_ins = 0;
861+
ngx_http_clojure_jvm_num_ins = 1;
862+
#endif
863+
ngx_http_clojure_global_cycle = NULL;
864+
ngx_http_clojure_pipe_exit_by_master();
865+
}
866+
846867
#if defined(_WIN32) || defined(WIN32)
847868
static ngx_int_t ngx_http_clojure_quit_master(ngx_cycle_t *cycle) {
848869
u_long n;
@@ -914,6 +935,8 @@ static void ngx_http_clojure_process_exit(ngx_cycle_t *cycle) {
914935
}
915936
}
916937

938+
ngx_http_clojure_destroy_memory_util(cycle->log);
939+
ngx_http_clojure_destory_socket_util();
917940
ngx_http_clojure_close_jvm();
918941
}
919942

@@ -1012,13 +1035,16 @@ static ngx_int_t ngx_http_clojure_process_init(ngx_cycle_t *cycle) {
10121035
return NGX_OK;
10131036
}
10141037

1015-
if (mcf->jvm_disable_all || mcf->jvm_path.len == NGX_CONF_UNSET_SIZE) {
1038+
if (!ngx_http_clojure_is_embeded_by_jse
1039+
&& (mcf->jvm_disable_all || mcf->jvm_path.len == NGX_CONF_UNSET_SIZE) ) {
10161040
return NGX_OK;
10171041
}
10181042

10191043

10201044
#if !(NGX_WIN32)
1021-
ngx_setproctitle("worker process");
1045+
if (!ngx_http_clojure_is_embeded_by_jse) {
1046+
ngx_setproctitle("worker process");
1047+
}
10221048
#else
10231049
ngx_http_clojure_jvm_be_mad_times = &ngx_http_clojure_jvm_be_mad_times_ins;
10241050
ngx_http_clojure_jvm_num = &ngx_http_clojure_jvm_num_ins;
@@ -1144,7 +1170,7 @@ static ngx_int_t ngx_http_clojure_postconfiguration(ngx_conf_t *cf) {
11441170
#endif
11451171
}
11461172

1147-
if (mcf->jvm_options == NGX_CONF_UNSET_PTR) {
1173+
if (!ngx_http_clojure_is_embeded_by_jse && mcf->jvm_options == NGX_CONF_UNSET_PTR) {
11481174
ngx_log_error(NGX_LOG_ERR, cf->log, 0, "no jvm_options configured!");
11491175
return NGX_ERROR ;
11501176
}

src/c/ngx_http_clojure_socket.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,3 +706,7 @@ int ngx_http_clojure_init_socket_util() {
706706

707707
return NGX_HTTP_CLOJURE_JVM_OK;
708708
}
709+
710+
void ngx_http_clojure_destory_socket_util() {
711+
ngx_http_clojure_init_socket_flag = NGX_HTTP_CLOJURE_JVM_ERR;
712+
}

src/c/ngx_http_clojure_socket.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,6 @@ int ngx_http_clojure_socket_upstream_shutdown(ngx_http_clojure_socket_upstream_t
155155
/*for jni init*/
156156
int ngx_http_clojure_init_socket_util();
157157

158+
void ngx_http_clojure_destory_socket_util();
159+
158160
#endif /* NGX_HTTP_CLOJURE_SOCKET_H_ */

0 commit comments

Comments
 (0)