[plt-scheme] capturing output from different threads
On Thu, 2008-03-06 at 16:20 -0700, Matthew Flatt wrote:
> At Thu, 06 Mar 2008 21:17:50 +0000, Dave Griffiths wrote:
> > Scheme_Object *outport=NULL;
> > Scheme_Object *errport=NULL;
> >
> > void interpret(Scheme_Env *e, char *code)
> > {
> > mz_jmp_buf * volatile save=NULL, fresh;
> > char *msg=NULL;
> >
> > MZ_GC_DECL_REG(5);
> > MZ_GC_VAR_IN_REG(0, outport);
> > MZ_GC_VAR_IN_REG(1, errport);
>
> Use MZ_GC_VAR_IN_REG() for stack-allocated locations, only.
>
> Use MZ_REGISTER_STATIC() to register a static location. A static
> variable should be registered only once, and MZ_GC_UNREG() doesn't
> remove the registration (i.e,. it's completely indpendent of registered
> stack bindings).
Yup, that fixes this example - but I'm not using static or global data
in my other code so my search continues :(
One thing I've just noticed is that the output from the thread in that
example doesn't actually come through the outport - with this slightly
modified example, where I've prepended the output with "!!!" - any
ideas?:
#define MZ_PRECISE_GC
#include <scheme.h>
Scheme_Object *outport=NULL;
Scheme_Object *errport=NULL;
void interpret(Scheme_Env *e, char *code)
{
mz_jmp_buf * volatile save=NULL, fresh;
char *msg=NULL;
MZ_GC_DECL_REG(4);
MZ_GC_VAR_IN_REG(0, e);
MZ_GC_VAR_IN_REG(1, msg);
MZ_GC_VAR_IN_REG(2, save);
MZ_GC_VAR_IN_REG(3, code);
MZ_GC_REG();
save = scheme_current_thread->error_buf;
scheme_current_thread->error_buf = &fresh;
if (scheme_setjmp(scheme_error_buf))
{
scheme_current_thread->error_buf = save;
exit(-1);
}
else
{
scheme_eval_string_all(code, e, 1);
}
scheme_current_thread->error_buf = save;
long size=0;
msg=scheme_get_sized_byte_string_output(outport,&size);
if (size>0) printf("!!! %s\n",msg);
msg=scheme_get_sized_byte_string_output(errport,&size);
if (size>0) printf("!!! %s\n",msg);
MZ_GC_UNREG();
}
int main(int argc, char *argv[])
{
void *stack_start;
stack_start = (void *)&stack_start;
Scheme_Env *e = NULL;
Scheme_Config *config = NULL;
MZ_GC_DECL_REG(2);
MZ_GC_VAR_IN_REG(0, e);
MZ_GC_VAR_IN_REG(1, config);
scheme_set_stack_base( &__gc_var_stack__, 1);
MZ_GC_REG();
e = scheme_basic_env();
MZ_REGISTER_STATIC(outport);
MZ_REGISTER_STATIC(errport);
outport = scheme_make_byte_string_output_port();
errport = scheme_make_byte_string_output_port();
config = scheme_current_config();
scheme_set_param(config, MZCONFIG_OUTPUT_PORT, outport);
scheme_set_param(config, MZCONFIG_ERROR_PORT, errport);
interpret(e,"\
(define (go) \
(define (loop n)\
(printf \"hello~n\")\
(loop (+ n 1))) \
(display \"going...\")(newline)\
(loop 0))\
(thread go)");
while(1)
{
interpret(e,"");
}
MZ_GC_UNREG();
return 0;
}