bug-guile
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

guile 2.0.1 fluid *current-language* failed to initialize in multi-threa


From: 亚光唐
Subject: guile 2.0.1 fluid *current-language* failed to initialize in multi-thread app
Date: Mon, 30 May 2011 01:16:44 +0800

I intend to use two thread eval some string in my app, but I found the
the child thread
will throw an exception when execute 'scm_eval_string' function.

I print out the call stack and check the source code, I found that the
*current-language*
variable is '#f" in the child thread. I think there must be something wrong.


Test environment:
Linux tyg-THINK 2.6.37 #7 SMP Tue Feb 22 11:25:54 CST 2011 x86_64
Intel(R) Core(TM) i3 CPU       M 370  @ 2.40GHz GenuineIntel GNU/Linux
x86_64-unknown-linux-gnu (slackware 13.2)
gcc 4.4.4
guile 2.0.1 build with '--prefix=/usr/local/stow/guile-2.0.1'
'BDW_GC_CFLAGS=-I/usr/local/include' 'BDW_GC_LIBS=-L/usr/local/libs
-lgc'
BWD gc 7.1 with default config

Following code will reproduce the bug.

g++ -g -Wall -pipe -pthread
-I/usr/local/stow/guile-2.0.1/include/guile/2.0 -lguile-2.0
bug_repro.cpp   -o bug_repro

// 
---------------------------------------------------------------------------------------------------------------------------------------------------


#include <libguile.h>
#include <pthread.h>
#include <stdio.h>

#define MAXLINE 1024

static SCM catch_body(void *data)
{
    char buf[MAXLINE];
    char *s = (char*)data;
    snprintf(buf, MAXLINE, "%s", s);
    SCM ret_val = scm_eval_string(scm_from_locale_string(buf));
    return ret_val;
}

static SCM catch_handler(void *data, SCM tag, SCM throw_args)
{
    char *stag = scm_to_locale_string(scm_symbol_to_string(tag));
    printf("--- catch %s: %s\n", stag, (char*)data);
    free(stag);
    return SCM_BOOL_T;
}

static SCM preunwind_handler(void *data, SCM key, SCM parameters)
{
    /* Capture the stack here: */
    *(SCM *)data = scm_make_stack (SCM_BOOL_T, SCM_EOL);
    return SCM_BOOL_T;
}

static const char * const str1 = "(display \"This is string A\") (newline)";
static const char * const str2 = "(display \"This is string B\") (newline)";

void *eval_string(void *argp)
{
    char *str = (char*)argp;

    SCM captured_stack = SCM_BOOL_F;

    // eval string.
    scm_c_catch (SCM_BOOL_T, catch_body, str, catch_handler, str,
                 preunwind_handler, &captured_stack);

    // print call stack on error.
    SCM port = scm_open_output_string ();
    if (captured_stack != SCM_BOOL_F) {
        scm_display_backtrace (captured_stack, port, SCM_BOOL_F, SCM_BOOL_F);
        SCM scm_str = scm_get_output_string (port);
        char *stack_str = scm_to_locale_string(scm_str);
        printf("%s", stack_str);
        scm_close_output_port(port);
    }
    return 0;
}

static void* run_thread(void * arg)
{
    scm_with_guile(eval_string, (void*)str2);
    return 0;
}

static void
inner_main (void *closure, int argc, char **argv)
{
    // eval string A
    eval_string((void*)str1);

    pthread_t tid;
    // create new thread and eval string B
    if (pthread_create(&tid, 0, run_thread, 0) < 0) {
        exit(1);
    }

    pthread_join(tid, 0);

    exit(0);
}

int main(int argc, char** argv)
{
    scm_boot_guile(argc, argv, inner_main, 0);
}

// 
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------



reply via email to

[Prev in Thread] Current Thread [Next in Thread]