-/* $Id: js_gcroot.c,v 1.1 2006/10/05 17:43:06 mmondor Exp $ */
+/* $Id: js_gcroot.c,v 1.2 2006/10/05 18:43:30 mmondor Exp $ */
/*
* Copyright (c) 2006, Matthew Mondor
/*
+ * We define a structure allowing to continue storing context-specific
+ * user-data, while also storing the gcroot which requires a unique address in
+ * the process space (and can't be on the stack) to be rooted.
+ */
+typedef struct cxspec {
+ JSObject *gcroot;
+ void *udata;
+} cxspec_t;
+
+
+
+/*
* Static globals
*/
JS_FinalizeStub
};
-/*
- * Exported globals
- */
-JSObject *gcroot = NULL;
-
/*
*/
JSBool
-js_InitGCRootClass(JSContext *cx)
+js_InitGCRoot(JSContext *cx)
{
+ cxspec_t *d = NULL;
+
+ if ((d = malloc(sizeof(cxspec_t))) == NULL) {
+ (void) fprintf(stderr, "GCRoot: malloc()\n");
+ return JS_FALSE;
+ }
+ d->udata = NULL;
/* Instantiate new object */
- if ((gcroot = JS_NewObject(cx, &gcroot_class, NULL, NULL)) == NULL) {
+ if ((d->gcroot = JS_NewObject(cx, &gcroot_class, NULL, NULL))
+ == NULL) {
(void) fprintf(stderr, "GCRoot: JS_NewObject(gcroot)\n");
- return JS_FALSE;
+ goto err;
}
- if (!JS_AddRoot(cx, &gcroot)) {
+ if (!JS_AddRoot(cx, &d->gcroot)) {
(void) fprintf(stderr, "GCRoot: JS_AddRoot(gcroot)\n");
- gcroot = NULL;
- return JS_FALSE;
+ goto err;
}
+ JS_SetContextPrivate(cx, d);
return JS_TRUE;
+
+err:
+ if (d != NULL)
+ free(d);
+
+ return JS_FALSE;
}
void
-js_DestroyGCRootClass(JSContext *cx)
+js_DestroyGCRoot(JSContext *cx)
{
-
- if (gcroot != NULL) {
- if (!JS_RemoveRoot(cx, &gcroot))
- (void) fprintf(stderr,
- "GCRoot: JS_RemoveRoot(gcroot)\n");
- gcroot = NULL;
+ cxspec_t *d;
+
+ if ((d = JS_GetContextPrivate(cx)) != NULL) {
+ if (d->gcroot != NULL) {
+ if (!JS_RemoveRoot(cx, &d->gcroot))
+ (void) fprintf(stderr,
+ "GCRoot: JS_RemoveRoot(gcroot)\n");
+ }
+ free(d);
+ JS_SetContextPrivate(cx, NULL);
}
}
+
+JSObject *
+js_GCRoot(JSContext *cx)
+{
+ cxspec_t *d;
+
+ d = JS_GetContextPrivate(cx);
+ assert(d != NULL);
+
+ return d->gcroot;
+}
+
+void
+js_GCRoot_udata_set(JSContext *cx, void *udata)
+{
+ cxspec_t *d;
+
+ d = JS_GetContextPrivate(cx);
+ assert(d != NULL);
+
+ d->udata = udata;
+}
+
+void *
+js_GCroot_udata_get(JSContext *cx)
+{
+ cxspec_t *d;
+
+ d = JS_GetContextPrivate(cx);
+ assert(d != NULL);
+
+ return d->udata;
+}
-/* $Id: js_gcroot.h,v 1.1 2006/10/05 17:43:06 mmondor Exp $ */
+/* $Id: js_gcroot.h,v 1.2 2006/10/05 18:43:30 mmondor Exp $ */
/*
* Copyright (c) 2006, Matthew Mondor
#include <js_gcroot.h>
-extern JSBool js_InitGCRootClass(JSContext *);
-extern void js_DestroyGCRootClass(JSContext *);
-
-/* This rooted object can be added properties to by any class as needed */
-extern JSObject *gcroot;
+extern JSBool js_InitGCRoot(JSContext *);
+extern void js_DestroyGCRoot(JSContext *);
+extern JSObject *js_GCRoot(JSContext *);
+extern void js_GCRoot_udata_set(JSContext *, void *);
+extern void *js_GCRoot_udata_get(JSContext *);
#endif
-/* $Id: js_pgsql.c,v 1.8 2006/10/05 17:43:06 mmondor Exp $ */
+/* $Id: js_pgsql.c,v 1.9 2006/10/05 18:43:30 mmondor Exp $ */
/*
* Copyright (c) 2006, Matthew Mondor
{
PGconn *pgc;
FILE *fh;
+ JSObject *gcroot;
*rval = OBJECT_TO_JSVAL(NULL);
* Unroot previously rooted File object, if any, then root newly
* provided File object.
*/
+ gcroot = js_GCRoot(cx);
+ assert(gcroot != NULL);
(void) JS_DeleteProperty(cx, gcroot, "trace_file_root");
if (!JS_DefineProperty(cx, gcroot, "trace_file_root", argv[0],
NULL, NULL, 0)) {
jsval *rval)
{
PGconn *pgc;
+ JSObject *gcroot;
*rval = OBJECT_TO_JSVAL(NULL);
/*
* Unroot previously rooted File object
*/
+ gcroot = js_GCRoot(cx);
+ assert(gcroot != NULL);
(void) JS_DeleteProperty(cx, gcroot, "trace_file_root");
PQuntrace(pgc);
-# $Id: GNUmakefile,v 1.2 2006/09/08 12:50:45 mmondor Exp $
+# $Id: GNUmakefile,v 1.3 2006/10/05 18:43:36 mmondor Exp $
CFLAGS += -Wall -DDEBUG
MMOBJS := $(addprefix ../../../mmlib/,mmpool.o mmlog.o mmreadcfg.o \
mmstring.o mmhash.o mmalarm.o mmheap.o mmlimitrate.o mmserver2.o)
-JSOBJS := $(addprefix ../../classes/,js_errno.o js_fd.o js_pgsql.o js_dir.o)
+JSOBJS := $(addprefix ../../classes/,js_gcroot.o js_errno.o js_fd.o js_file.o \
+ js_pgsql.o js_dir.o)
CFLAGS += $(JS_CFLAGS) $(PG_CFLAGS) -I. -I../../../mmlib -I../../classes
-/* $Id: js-appserv.c,v 1.2 2006/09/08 12:50:45 mmondor Exp $ */
+/* $Id: js-appserv.c,v 1.3 2006/10/05 18:43:36 mmondor Exp $ */
/*
* Copyright (C) 2006, Matthew Mondor
#include <mmstring.h>
#include <mmserver2.h>
+#include <js_gcroot.h>
#include <js_errno.h>
#include <js_fd.h>
#include <js_pgsql.h>
static void
context_error_reporter(JSContext *cx, const char *msg, JSErrorReport *rep)
{
+
syslog(LOG_NOTICE, "context_error_reporter() - %s : %s",
msg, rep->linebuf);
}
}
/* Wanted custom classes */
+ if (!js_InitGCRoot(ctx)) {
+ syslog(LOG_NOTICE, "context_create() - js_InitGCRoot()");
+ goto err;
+ }
if (!js_InitErrnoClass(ctx, *obj)) {
syslog(LOG_NOTICE, "context_create() - js_InitErrnoClass()");
goto err;
return ctx;
err:
- if (ctx)
+ if (ctx != NULL) {
+ js_DestroyGCRoot(ctx);
JS_DestroyContext(ctx);
+ }
return NULL;
}
}
if (p_ctx != NULL) {
(void) JS_RemoveRoot(p_ctx, &p_robj);
+ js_DestroyGCRoot(p_ctx);
JS_DestroyContext(p_ctx);
p_ctx = NULL;
}
err:
if (script && ctx)
JS_DestroyScript(ctx, script);
- if (ctx)
+ if (ctx) {
+ js_DestroyGCRoot(ctx);
JS_DestroyContext(ctx);
+ }
if (rt)
JS_DestroyRuntime(rt);
-# $Id: GNUmakefile,v 1.4 2006/09/25 23:06:28 mmondor Exp $
+# $Id: GNUmakefile,v 1.5 2006/10/05 18:43:38 mmondor Exp $
#CFLAGS += -g
CFLAGS += -Wall
GD_LDFLAGS := $(shell gdlib-config --ldflags --libs)
GD_LDFLAGS += -lgd
-OBJS := $(addprefix ../../classes/,js_fd.o js_errno.o js_signal.o js_file.o \
- js_pgsql.o js_dir.o js_fs.o js_gd.o)
+OBJS := $(addprefix ../../classes/,js_gcroot.o js_fd.o js_errno.o js_signal.o \
+ js_file.o js_pgsql.o js_dir.o js_fs.o js_gd.o)
OBJS += js-sh.o
CFLAGS += $(JS_CFLAGS) $(PG_CFLAGS) $(GD_CFLAGS) -I../../classes -Wall
-/* $Id: js-sh.c,v 1.6 2006/09/25 23:06:28 mmondor Exp $ */
+/* $Id: js-sh.c,v 1.7 2006/10/05 18:43:38 mmondor Exp $ */
/*
* Copyright (c) 2004-2005, Matthew Mondor
#include <jsapi.h>
+#include <js_gcroot.h>
#include <js_fd.h>
#include <js_errno.h>
#include <js_signal.h>
(cctx->global = JS_NewObject(cctx->ctx, &global_class, NULL,
NULL)) == NULL ||
!JS_InitStandardClasses(cctx->ctx, cctx->global) ||
+ !js_InitGCRoot(cctx->ctx) ||
(cctx->class_fd = js_InitFDClass(cctx->ctx, cctx->global))
== NULL ||
(cctx->class_errno = js_InitErrnoClass(cctx->ctx, cctx->global))
assert(cctx != NULL);
- if (cctx->ctx != NULL)
+ if (cctx->ctx != NULL) {
+ js_DestroyGCRoot(cctx->ctx);
JS_DestroyContext(cctx->ctx);
+ }
if (cctx->rt != NULL)
JS_DestroyRuntime(cctx->rt);