[plt-scheme] capturing output from different threads

From: Dave Griffiths (dave at pawfal.org)
Date: Sat Mar 8 14:08:25 EST 2008

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;
}







Posted on the users mailing list.