=================================================================== RCS file: /home/cvs/OpenXM/src/ox_ntl/oxserv.c,v retrieving revision 1.2 retrieving revision 1.7 diff -u -p -r1.2 -r1.7 --- OpenXM/src/ox_ntl/oxserv.c 2003/11/08 12:34:00 1.2 +++ OpenXM/src/ox_ntl/oxserv.c 2004/07/11 00:32:17 1.7 @@ -1,56 +1,41 @@ -/* $OpenXM: OpenXM/src/ox_ntl/oxserv.c,v 1.1 2003/11/03 03:11:21 iwane Exp $ */ +/* $OpenXM: OpenXM/src/ox_ntl/oxserv.c,v 1.6 2004/07/04 11:38:42 iwane Exp $ */ #include #include #include #include #include +#include #include "oxserv.h" #include "oxstack.h" +#include "gmp.h" +#include "gc/gc.h" -#define DPRINTF(x) printf x; fflush(stdout) +#define DPRINTF(x) printf x; (void)fflush(stdout) -#if 0 -/*===========================================================================* - * for DEBUG - *===========================================================================*/ -#include -void -dprintf(const char *fmt, ...) -{ - FILE *fp; - va_list ap; - va_start(ap, fmt); - - fp = fopen("error.txt", "a"); +#define FP stdout +#define EPRINTF(x) fprintf x; (void)fflush(FP) - vfprintf(fp, fmt, ap); - fflush(fp); - fclose(fp); - - va_end(ap); -} -#endif - /*===========================================================================* * MACRO *===========================================================================*/ -#define MOXSERV_GET_CMO_TAG(m) ((G_getCmoTag == NULL) ? m->tag : G_getCmoTag(m)) +#define oxserv_get_cmo_tag(m) ((G_getCmoTag == NULL) ? m->tag : G_getCmoTag(m)) #define oxserv_delete_cmo(c) \ do { \ - if (G_DeleteCmo != NULL) \ - G_DeleteCmo(c); \ - else \ + if (c != NULL) { \ + if (G_DeleteCmo != NULL) \ + G_DeleteCmo((cmo *)c); \ + else \ c = NULL; \ + } \ } while (0) - /*===========================================================================* * Global Variables. *===========================================================================*/ @@ -58,6 +43,11 @@ do { \ static OXFILE *G_oxfilep = NULL; static cmo_mathcap *G_oxserv_mathcap = NULL; +/* signal */ +int G_oxserv_sigusr1flag = 0; +int G_oxserv_sigusr1cnt = 0; +static jmp_buf G_jmpbuf; + /* User Function */ static void (*G_userExecuteFunction)(const char *, cmo **, int) = NULL; static void (*G_userExecuteStringParser)(const char *) = NULL; @@ -68,7 +58,56 @@ static void (*G_DeleteCmo)(cmo *) = NULL; static int (*G_getCmoTag)(cmo *) = NULL; + /*===========================================================================* + * CMO_ERROR2 + *===========================================================================*/ +#define new_cmo_error2_string(msg) new_cmo_error2((cmo *)new_cmo_string(msg)) + + +static void +oxserv_push_errormes(char *msg) +{ + EPRINTF((FP, "%s\n", msg)); + oxstack_push((cmo *)new_cmo_error2_string(msg)); +} + +/*===========================================================================* + * synchronized malloc + *===========================================================================*/ +void * +oxserv_malloc(size_t size) +{ + void *ptr; + + BLOCK_INPUT(); + ptr = GC_malloc(size); + UNBLOCK_INPUT(); + + return (ptr); +} + +void +oxserv_free(void *ptr, size_t size) +{ + /* nothing */ +} + +void * +oxserv_realloc(void *org, size_t old, size_t size) +{ + void *ptr; + + BLOCK_INPUT(); + ptr = GC_realloc(org, size); + UNBLOCK_INPUT(); + + return (ptr); +} + + + +/*===========================================================================* * OX_SERVER *===========================================================================*/ @@ -83,11 +122,17 @@ static int (*G_getCmoTag)(cmo *) = NULL; static void oxserv_sm_popCMO(OXFILE *fd) { - cmo *m = oxstack_pop(); + cmo *m, *n; + m = oxstack_pop(); if (m == NULL) { + EPRINTF((FP, "stack underflow in popCMO\n")); m = new_cmo_null(); } else if (G_convertCmo) { - m = G_convertCmo(m); + n = G_convertCmo(m); + if (m != n) { + oxserv_delete_cmo(m); + m = n; + } } send_ox_cmo(fd, m); @@ -110,8 +155,10 @@ oxserv_sm_popString(OXFILE *fd) cmo *m = oxstack_pop(); cmo_string *m_str; - if (m == NULL) + if (m == NULL) { + EPRINTF((FP, "stack underflow in popString\n")); m = new_cmo_null(); + } str = new_string_set_cmo(m); @@ -120,7 +167,7 @@ oxserv_sm_popString(OXFILE *fd) send_ox_cmo(fd, (cmo *)m_str); oxserv_delete_cmo(m); - oxserv_delete_cmo((cmo *)m_str); + oxserv_delete_cmo(m_str); /* free(str); */ } @@ -141,6 +188,10 @@ oxserv_sm_pops() int i; c = (cmo_int32 *)oxstack_pop(); /* suppose */ + if (c == NULL) { + EPRINTF((FP, "stack underflow in pops\n")); + return ; + } n = oxstack_get_stack_pointer(); if (c->i < n) @@ -151,7 +202,7 @@ oxserv_sm_pops() oxserv_delete_cmo(m); } - oxserv_delete_cmo((cmo *)c); + oxserv_delete_cmo(c); } @@ -252,7 +303,7 @@ oxserv_mathcap_init(int ver, char *vstr, char *sysname mathcap_init(ver, vstr, sysname, cmos, sms); - oxserv_delete_cmo((cmo *)G_oxserv_mathcap); + oxserv_delete_cmo(G_oxserv_mathcap); G_oxserv_mathcap = mathcap_get(new_mathcap()); } @@ -286,6 +337,10 @@ static void oxserv_sm_executeStringByLocalParserInBatchMode(void) { cmo_string *str = (cmo_string *)oxstack_peek(); + if (str == NULL) { + oxserv_push_errormes("stack underflow in executeStringByLocalParserInBatchMode"); + return ; + } G_userExecuteStringParser(str->s); } @@ -301,6 +356,10 @@ static void oxserv_sm_executeStringByLocalParser(void) { cmo_string *str = (cmo_string *)oxstack_pop(); + if (str == NULL) { + oxserv_push_errormes("stack underflow in executeStringByLocalParser"); + return ; + } G_userExecuteStringParser(str->s); } @@ -311,6 +370,8 @@ oxserv_sm_executeStringByLocalParser(void) * pop s as a function name, pop n as the number of arguments and to execute a * local function s with n arguments poped from the stack. * + * suppose G_userExecuteFunction not equal NULL + * * PARAM : NONE * RETURN: NONE *****************************************************************************/ @@ -320,10 +381,25 @@ oxserv_sm_executeFunction(void) int i; cmo_string *name = (cmo_string *)oxstack_pop(); cmo_int32 *cnt = (cmo_int32 *)oxstack_pop(); - cmo **arg = (cmo **)malloc(cnt->i * sizeof(cmo *)); + cmo **arg; + + if (name == NULL || cnt == NULL) { + oxserv_push_errormes("stack underflow in executeFunction"); + return ; + } + + arg = (cmo **)malloc(cnt->i * sizeof(cmo *)); for (i = 0; i < cnt->i; i++) { arg[i] = oxstack_pop(); + if (arg[i] == NULL) { + oxserv_push_errormes("stack underflow in executeFunction"); + + for (i--; i >= 0; i--) + oxserv_delete_cmo(arg[i]); + free(arg); + return ; + } } /* user function */ @@ -334,8 +410,8 @@ oxserv_sm_executeFunction(void) oxserv_delete_cmo(arg[i]); } - oxserv_delete_cmo((cmo *)name); - oxserv_delete_cmo((cmo *)cnt); + oxserv_delete_cmo(name); + oxserv_delete_cmo(cnt); free(arg); } @@ -351,11 +427,17 @@ static void oxserv_sm_pushCMOtag() { cmo *c = oxstack_peek(); - cmo_int32 *tag = new_cmo_int32(MOXSERV_GET_CMO_TAG(c)); + cmo_int32 *tag = new_cmo_int32(oxserv_get_cmo_tag(c)); oxstack_push((cmo *)tag); } +/***************************************************************************** + * -- SM_dupErrors -- + * + * PARAM : NONE + * RETURN: NONE + *****************************************************************************/ static void oxserv_sm_dupErrors() { @@ -375,71 +457,110 @@ oxserv_sm_dupErrors() oxstack_push((cmo *)list); } -static void + + + +/***************************************************************************** + * -- SM_control_reset_connection -- signal handler for SIGUSR1 -- + * + * PARAM : NONE + * + * : if (sig == 0) called UNBLOCK_INPUT() + * RETURN: NONE + *****************************************************************************/ +void oxserv_sm_control_reset_connection(int sig) { int tag; OXFILE *fd = G_oxfilep; - DPRINTF(("reset -- start\n")); + if (G_oxserv_sigusr1cnt > 0) { + G_oxserv_sigusr1flag = 1; + return ; + } + + + DPRINTF(("reset -- start ==> ")); + G_oxserv_sigusr1flag = 0; + send_ox_tag(fd, OX_SYNC_BALL); oxstack_init_stack(); for (;;) { tag = receive_ox_tag(fd); - DPRINTF(("[%d=0x%x]", tag, tag)); + DPRINTF(("[OX:%d=0x%x]", tag, tag)); if (tag == OX_SYNC_BALL) break; if (tag == OX_DATA) receive_cmo(fd); + else + receive_int32(fd); } - DPRINTF(("-- end.\n")); + DPRINTF((" <== end.\n")); + + + longjmp(G_jmpbuf, sig); } +/***************************************************************************** + * execute sm command + * + * PARAM : NONE + * RETURN: NONE + *****************************************************************************/ static int -oxserv_receive_and_execute_sm_command(OXFILE *fd) +oxserv_execute_sm_command(OXFILE *fd, int code) { - int code = receive_int32(fd); + DPRINTF(("[SM:%d=0x%x]", code, code)); + switch (code) { - case SM_popCMO: + case SM_popCMO: /* 262 */ oxserv_sm_popCMO(fd); break; - case SM_executeStringByLocalParser: + case SM_executeStringByLocalParser: /* 268 */ if (G_userExecuteStringParser) oxserv_sm_executeStringByLocalParser(); break; - case SM_executeStringByLocalParserInBatchMode: + case SM_executeStringByLocalParserInBatchMode: /* 274 */ if (G_userExecuteStringParser) oxserv_sm_executeStringByLocalParserInBatchMode(); break; - case SM_pops: + case SM_pops: /* 265 */ oxserv_sm_pops(); break; - case SM_popString: + case SM_popString: /* 263 */ oxserv_sm_popString(fd); break; - case SM_getsp: + case SM_getsp: /* 275 */ oxserv_sm_getsp(); break; - case SM_mathcap: + case SM_mathcap: /* 264 */ oxserv_sm_mathcap(); break; - case SM_setMathCap: + case SM_setMathCap: /* 273 */ /* dont support */ oxstack_pop(); break; - case SM_executeFunction: + case SM_executeFunction: /* 269 */ if (G_userExecuteFunction) oxserv_sm_executeFunction(); break; - case SM_pushCMOtag: + case SM_pushCMOtag: /* 277 */ oxserv_sm_pushCMOtag(); break; - case SM_dupErrors: + case SM_dupErrors: /* 276 */ oxserv_sm_dupErrors(); break; + case SM_popSerializedLocalObject: + case SM_setName: + case SM_evalName: + case SM_beginBlock: + case SM_endBlock: + case SM_shutdown: + case SM_executeFunctionAndPopCMO: + case SM_executeFunctionAndPopSerializedLocalObject: case SM_control_reset_connection: case SM_control_reset_connection_server: default: @@ -456,25 +577,28 @@ oxserv_receive_and_execute_sm_command(OXFILE *fd) * PARAM : fd : OXFILE * RETURN: NONE *****************************************************************************/ -int -oxserv_receive(OXFILE *fd) +static int +oxserv_ox_receive(OXFILE *fd) { int tag; cmo *c; int ret = OXSERV_SUCCESS; + int code; tag = receive_ox_tag(fd); switch (tag) { case OX_DATA: + BLOCK_INPUT(); c = receive_cmo(fd); - DPRINTF(("[CMO:%d]", c->tag)); + UNBLOCK_INPUT(); + DPRINTF(("[CMO:%d=0x%x]", c->tag, c->tag)); oxstack_push(c); break; case OX_COMMAND: - DPRINTF(("[SM:%d=0x%x]", tag, tag)); - ret = oxserv_receive_and_execute_sm_command(fd); + code = receive_int32(fd); + ret = oxserv_execute_sm_command(fd, code); break; default: @@ -485,7 +609,28 @@ oxserv_receive(OXFILE *fd) return (ret); } +int +oxserv_receive(OXFILE *fd) +{ + int i = 0; + int ret; + ret = setjmp(G_jmpbuf); + if (ret == 0) { + DPRINTF(("setjmp first time -- %d\n", ret)); + } else { + DPRINTF(("setjmp return from longjmp() -- %d -- \n", ret)); + } + + for (;; i++) { + ret = oxserv_ox_receive(fd); + if (ret != OXSERV_SUCCESS) + break; + } + return (ret); +} + + /***************************************************************************** * initialize oxserver * @@ -500,6 +645,8 @@ oxserv_init(OXFILE *oxfp, int ver, char *vstr, char *s { int ret; + DPRINTF(("init start\n")); + ret = oxstack_init_stack(); if (ret != OXSERV_SUCCESS) return (ret); @@ -510,6 +657,10 @@ oxserv_init(OXFILE *oxfp, int ver, char *vstr, char *s signal(SIGUSR1, oxserv_sm_control_reset_connection); + /* initialize GMP memory functions. */ + mp_set_memory_functions(oxserv_malloc, oxserv_realloc, oxserv_free); + + /* session start */ oxf_determine_byteorder_server(oxfp); return (OXSERV_SUCCESS); @@ -517,7 +668,7 @@ oxserv_init(OXFILE *oxfp, int ver, char *vstr, char *s /***************************************************************************** - * set oxserver + * set oxserver behavior * * PARAM : mode : mode * : @@ -564,6 +715,8 @@ oxserv_set(int mode, void *ptr, void *rsv) void oxserv_dest() { + oxserv_delete_cmo(G_oxserv_mathcap); + oxstack_dest(); } @@ -574,7 +727,7 @@ oxserv_dest() *===========================================================================*/ -cmo * +void oxserv_executeFunction(const char *func, cmo **arg, int argc) { int i; @@ -585,7 +738,7 @@ oxserv_executeFunction(const char *func, cmo **arg, in printf("\t%2d: %s\n", i, new_string_set_cmo(arg[i])); } - return ((cmo *)new_cmo_int32(0)); + return ; } /***************************************************************************** @@ -605,18 +758,14 @@ main(int argc, char *argv[]) ox_stderr_init(stderr); - oxserv_init(oxfp, 0, "$Date: 2003/11/08 12:34:00 $", "oxserv", NULL, NULL); + oxserv_set(OXSERV_SET_EXECUTE_FUNCTION, oxserv_executeFunction, NULL); - DPRINTF(("main - start\n")); - for (i = 0;; i++) { - DPRINTF(("@")); - ret = oxserv_receive(oxfp); - if (ret != OXSERV_SUCCESS) - break; - } + oxserv_init(oxfp, 0, "$Date: 2004/07/11 00:32:17 $", "oxserv", NULL, NULL); + ret = oxserv_receive(oxfp); + + oxserv_dest(); oxf_close(oxfp); - oxserv_delete_cmo((cmo *)G_oxserv_mathcap); return (0); }