From fc656d6b3bd80ae49edf03e16aa903382a331e87 Mon Sep 17 00:00:00 2001 From: deuce <> Date: Thu, 4 Dec 2008 19:45:28 +0000 Subject: [PATCH] Use a pool of JSRuntimes to avoid the 128 threads with runtime issue with SpiderMonkey 1.7 --- src/sbbs3/ftpsrvr.c | 5 +++-- src/sbbs3/js_global.c | 5 +++-- src/sbbs3/js_rtpool.c | 47 +++++++++++++++++++++++++++++++++++++++++++ src/sbbs3/js_rtpool.h | 45 +++++++++++++++++++++++++++++++++++++++++ src/sbbs3/jsexec.c | 5 +++-- src/sbbs3/mailsrvr.c | 5 +++-- src/sbbs3/main.cpp | 5 +++-- src/sbbs3/objects.mk | 1 + src/sbbs3/services.c | 9 +++++---- src/sbbs3/websrvr.c | 9 +++++---- 10 files changed, 118 insertions(+), 18 deletions(-) create mode 100644 src/sbbs3/js_rtpool.c create mode 100644 src/sbbs3/js_rtpool.h diff --git a/src/sbbs3/ftpsrvr.c b/src/sbbs3/ftpsrvr.c index d740f231dd..3da30c8eb8 100644 --- a/src/sbbs3/ftpsrvr.c +++ b/src/sbbs3/ftpsrvr.c @@ -51,6 +51,7 @@ #include "text.h" /* TOTAL_TEXT */ #include "ftpsrvr.h" #include "telnet.h" +#include "js_rtpool.h" /* Constants */ @@ -3858,7 +3859,7 @@ static void ctrl_thread(void* arg) lprintf(LOG_DEBUG,"%04d JavaScript: Creating runtime: %lu bytes" ,sock,startup->js.max_bytes); - if((js_runtime = JS_NewRuntime(startup->js.max_bytes))==NULL) { + if((js_runtime = jsrt_GetNew(startup->js.max_bytes))==NULL) { lprintf(LOG_ERR,"%04d !ERROR creating JavaScript runtime",sock); sockprintf(sock,"451 Error creating JavaScript runtime"); filepos=0; @@ -4462,7 +4463,7 @@ static void ctrl_thread(void* arg) if(js_runtime!=NULL) { lprintf(LOG_DEBUG,"%04d JavaScript: Destroying runtime",sock); - JS_DestroyRuntime(js_runtime); + jsrt_Release(js_runtime); } #endif diff --git a/src/sbbs3/js_global.c b/src/sbbs3/js_global.c index aafebba707..25eae3b3d0 100644 --- a/src/sbbs3/js_global.c +++ b/src/sbbs3/js_global.c @@ -42,6 +42,7 @@ #include "base64.h" #include "htmlansi.h" #include "ini_file.h" +#include "js_rtpool.h" /* SpiderMonkey: */ #include <jsfun.h> @@ -124,7 +125,7 @@ static void background_thread(void* arg) js_enqueue_value(bg->cx, bg->msg_queue, result, NULL); JS_DestroyScript(bg->cx, bg->script); JS_DestroyContext(bg->cx); - JS_DestroyRuntime(bg->runtime); + jsrt_Release(bg->runtime); free(bg); } @@ -255,7 +256,7 @@ js_load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) bg->branch.counter=0; bg->branch.gc_attempts=0; - if((bg->runtime = JS_NewRuntime(JAVASCRIPT_MAX_BYTES))==NULL) + if((bg->runtime = jsrt_GetNew(JAVASCRIPT_MAX_BYTES))==NULL) return(JS_FALSE); if((bg->cx = JS_NewContext(bg->runtime, JAVASCRIPT_CONTEXT_STACK))==NULL) diff --git a/src/sbbs3/js_rtpool.c b/src/sbbs3/js_rtpool.c new file mode 100644 index 0000000000..aafb646a54 --- /dev/null +++ b/src/sbbs3/js_rtpool.c @@ -0,0 +1,47 @@ +/* $Id$ */ + +#include "js_rtpool.h" + +struct jsrt_queue { + JSRuntime *rt; + int maxbytes; + int used; + int created; +}; + +#define JSRT_QUEUE_SIZE 128 +struct jsrt_queue jsrt_queue[JSRT_QUEUE_SIZE]; + +JSRuntime *jsrt_GetNew(int maxbytes) +{ + int i; + + for(i=0; i<JSRT_QUEUE_SIZE; i++) { + if(!jsrt_queue[i].created) { + jsrt_queue[i].rt=JS_NewRuntime(maxbytes); + if(jsrt_queue[i].rt != NULL) { + jsrt_queue[i].maxbytes=maxbytes; + jsrt_queue[i].created=1; + jsrt_queue[i].used=0; + } + } + if(jsrt_queue[i].created && jsrt_queue[i].maxbytes == maxbytes && jsrt_queue[i].used == 0) { + jsrt_queue[i].used=1; + return(jsrt_queue[i].rt); + } + } + + return(NULL); +} + +void jsrt_Release(JSRuntime *rt) +{ + int i; + + for(i=0; i<JSRT_QUEUE_SIZE; i++) { + if(rt==jsrt_queue[i].rt) { + jsrt_queue[i].used=0; + /* TODO: Clear "stuff"? */ + } + } +} diff --git a/src/sbbs3/js_rtpool.h b/src/sbbs3/js_rtpool.h new file mode 100644 index 0000000000..56b7edd999 --- /dev/null +++ b/src/sbbs3/js_rtpool.h @@ -0,0 +1,45 @@ +/* $Id$ */ + +#ifndef _JS_RTPOOL_H_ +#define _JS_RTPOOL_H_ + +#ifdef __unix__ + #define XP_UNIX +#else + #define XP_PC + #define XP_WIN +#endif +#include <jsapi.h> + +#ifdef DLLEXPORT +#undef DLLEXPORT +#endif +#ifdef DLLCALL +#undef DLLCALL +#endif +#ifdef _WIN32 + #ifdef SBBS_EXPORTS + #define DLLEXPORT __declspec(dllexport) + #else + #define DLLEXPORT __declspec(dllimport) + #endif + #ifdef __BORLANDC__ + #define DLLCALL __stdcall + #else + #define DLLCALL + #endif +#else /* !_WIN32 */ + #define DLLEXPORT + #define DLLCALL +#endif + +#if defined(__cplusplus) +extern "C" { +#endif +DLLEXPORT JSRuntime * DLLCALL jsrt_GetNew(int maxbytes); +DLLEXPORT void DLLCALL jsrt_Release(JSRuntime *); +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/src/sbbs3/jsexec.c b/src/sbbs3/jsexec.c index 552889f9db..0385f8658d 100644 --- a/src/sbbs3/jsexec.c +++ b/src/sbbs3/jsexec.c @@ -45,6 +45,7 @@ #include "sbbs.h" #include "ciolib.h" +#include "js_rtpool.h" #define DEFAULT_LOG_LEVEL LOG_DEBUG /* Display all LOG levels */ #define DEFAULT_ERR_LOG_LVL LOG_WARNING @@ -570,7 +571,7 @@ static BOOL js_init(char** environ) fprintf(statfp,"JavaScript: Creating runtime: %lu bytes\n" ,js_max_bytes); - if((js_runtime = JS_NewRuntime(js_max_bytes))==NULL) + if((js_runtime = jsrt_GetNew(js_max_bytes))==NULL) return(FALSE); fprintf(statfp,"JavaScript: Initializing context (stack: %lu bytes)\n" @@ -1023,7 +1024,7 @@ int main(int argc, char **argv, char** environ) fprintf(statfp,"JavaScript: Destroying context\n"); JS_DestroyContext(js_cx); fprintf(statfp,"JavaScript: Destroying runtime\n"); - JS_DestroyRuntime(js_runtime); + jsrt_Release(js_runtime); } while((recycled || loop) && !terminated); diff --git a/src/sbbs3/mailsrvr.c b/src/sbbs3/mailsrvr.c index 5bb693d971..7b41acfd52 100644 --- a/src/sbbs3/mailsrvr.c +++ b/src/sbbs3/mailsrvr.c @@ -56,6 +56,7 @@ #include "ini_file.h" #include "netwrap.h" /* getNameServerList() */ #include "xpendian.h" +#include "js_rtpool.h" /* Constants */ #define FORWARD "forward:" @@ -1609,7 +1610,7 @@ js_mailproc(SOCKET sock, client_t* client, user_t* user lprintf(LOG_DEBUG,"%04d JavaScript: Creating runtime: %lu bytes\n" ,sock, startup->js.max_bytes); - if((js_runtime = JS_NewRuntime(startup->js.max_bytes))==NULL) + if((js_runtime = jsrt_GetNew(startup->js.max_bytes))==NULL) break; lprintf(LOG_DEBUG,"%04d JavaScript: Initializing context (stack: %lu bytes)\n" @@ -1718,7 +1719,7 @@ js_mailproc(SOCKET sock, client_t* client, user_t* user if(js_cx!=NULL) JS_DestroyContext(js_cx); if(js_runtime!=NULL) - JS_DestroyRuntime(js_runtime); + jsrt_Release(js_runtime); return(success); } diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp index 98ccf1e867..62de411898 100644 --- a/src/sbbs3/main.cpp +++ b/src/sbbs3/main.cpp @@ -39,6 +39,7 @@ #include "ident.h" #include "telnet.h" #include "netwrap.h" +#include "js_rtpool.h" #ifdef __unix__ #include <sys/un.h> @@ -980,7 +981,7 @@ bool sbbs_t::js_init(ulong* stack_frame) lprintf(LOG_DEBUG,"%s JavaScript: Creating runtime: %lu bytes" ,node,startup->js.max_bytes); - if((js_runtime = JS_NewRuntime(startup->js.max_bytes))==NULL) + if((js_runtime = jsrt_GetNew(startup->js.max_bytes))==NULL) return(false); lprintf(LOG_DEBUG,"%s JavaScript: Initializing context (stack: %lu bytes)" @@ -3186,7 +3187,7 @@ sbbs_t::~sbbs_t() if(js_runtime!=NULL) { lprintf(LOG_DEBUG,"%s JavaScript: Destroying runtime",node); - JS_DestroyRuntime(js_runtime); + jsrt_Release(js_runtime); js_runtime=NULL; } #endif diff --git a/src/sbbs3/objects.mk b/src/sbbs3/objects.mk index 65b6b7c0ee..ece9133980 100644 --- a/src/sbbs3/objects.mk +++ b/src/sbbs3/objects.mk @@ -50,6 +50,7 @@ OBJS = $(MTOBJODIR)$(DIRSEP)ansiterm$(OFILE) \ $(MTOBJODIR)$(DIRSEP)js_msg_area$(OFILE)\ $(MTOBJODIR)$(DIRSEP)js_msgbase$(OFILE)\ $(MTOBJODIR)$(DIRSEP)js_queue$(OFILE)\ + $(MTOBJODIR)$(DIRSEP)js_rtpool$(OFILE)\ $(MTOBJODIR)$(DIRSEP)js_server$(OFILE)\ $(MTOBJODIR)$(DIRSEP)js_socket$(OFILE)\ $(MTOBJODIR)$(DIRSEP)js_sprintf$(OFILE)\ diff --git a/src/sbbs3/services.c b/src/sbbs3/services.c index 69ed74c6ed..964d8acbca 100644 --- a/src/sbbs3/services.c +++ b/src/sbbs3/services.c @@ -59,6 +59,7 @@ #include "services.h" #include "ident.h" /* identify() */ #include "sbbs_ini.h" +#include "js_rtpool.h" /* Constants */ @@ -1063,7 +1064,7 @@ static void js_service_thread(void* arg) /* Initialize client display */ client_on(socket,&client,FALSE /* update */); - if((js_runtime=JS_NewRuntime(service->js.max_bytes))==NULL + if((js_runtime=jsrt_GetNew(service->js.max_bytes))==NULL || (js_cx=js_initcx(js_runtime,socket,&service_client,&js_glob))==NULL) { lprintf(LOG_ERR,"%04d !%s ERROR initializing JavaScript context" ,socket,service->protocol); @@ -1116,7 +1117,7 @@ static void js_service_thread(void* arg) } JS_DestroyContext(js_cx); /* Free Context */ - JS_DestroyRuntime(js_runtime); + jsrt_Release(js_runtime); if(service_client.user.number) { lprintf(LOG_INFO,"%04d %s Logging out %s" @@ -1177,7 +1178,7 @@ static void js_static_service_thread(void* arg) service_client.branch.terminated = &service->terminated; service_client.branch.auto_terminate = TRUE; - if((js_runtime=JS_NewRuntime(service->js.max_bytes))==NULL) { + if((js_runtime=jsrt_GetNew(service->js.max_bytes))==NULL) { lprintf(LOG_ERR,"%04d !%s ERROR initializing JavaScript runtime" ,service->socket,service->protocol); close_socket(service->socket); @@ -1222,7 +1223,7 @@ static void js_static_service_thread(void* arg) if(js_cx!=NULL) JS_DestroyContext(js_cx); /* Free Context */ - JS_DestroyRuntime(js_runtime); + jsrt_Release(js_runtime); if(service->clients) { lprintf(LOG_WARNING,"%04d %s !service terminating with %u active clients" diff --git a/src/sbbs3/websrvr.c b/src/sbbs3/websrvr.c index 20708da7b2..23dd3ff63f 100644 --- a/src/sbbs3/websrvr.c +++ b/src/sbbs3/websrvr.c @@ -65,6 +65,7 @@ #include "websrvr.h" #include "base64.h" #include "md5.h" +#include "js_rtpool.h" static const char* server_name="Synchronet Web Server"; static const char* newline="\r\n"; @@ -4394,7 +4395,7 @@ static BOOL js_setup(http_session_t* session) lprintf(LOG_INFO,"%04d JavaScript: Creating runtime: %lu bytes" ,session->socket,startup->js.max_bytes); - if((session->js_runtime=JS_NewRuntime(startup->js.max_bytes))==NULL) { + if((session->js_runtime=jsrt_GetNew(startup->js.max_bytes))==NULL) { lprintf(LOG_ERR,"%04d !ERROR creating JavaScript runtime",session->socket); return(FALSE); } @@ -5005,7 +5006,7 @@ void http_session_thread(void* arg) #ifndef ONE_JS_RUNTIME if(session.js_runtime!=NULL) { lprintf(LOG_INFO,"%04d JavaScript: Destroying runtime",socket); - JS_DestroyRuntime(session.js_runtime); + jsrt_Release(session.js_runtime); session.js_runtime=NULL; } #endif @@ -5462,7 +5463,7 @@ void DLLCALL web_server(void* arg) lprintf(LOG_INFO,"%04d JavaScript: Creating runtime: %lu bytes" ,server_socket,startup->js.max_bytes); - if((js_runtime=JS_NewRuntime(startup->js.max_bytes))==NULL) { + if((js_runtime=jsrt_GetNew(startup->js.max_bytes))==NULL) { lprintf(LOG_ERR,"%04d !ERROR creating JavaScript runtime",server_socket); /* Sleep 15 seconds then try again */ /* ToDo: Something better should be used here. */ @@ -5685,7 +5686,7 @@ void DLLCALL web_server(void* arg) #ifdef ONE_JS_RUNTIME if(js_runtime!=NULL) { lprintf(LOG_INFO,"%04d JavaScript: Destroying runtime",server_socket); - JS_DestroyRuntime(js_runtime); + jsrt_Release(js_runtime); js_runtime=NULL; } #endif -- GitLab