The problem you just found is intimately related to the other one. ECL uses a garbage collector, evaluation environments and other stuff that has to be created *for each* thread where you want to execute or evaluate Common Lisp code. In the simple modification you made the routine new_Command1 just evaluated a lisp form in a thread that was simply not prepared for it.
The solution is to construct one or more Common Lisp slave threads that are responsible for executing code and communicating the appropriate output to the master threads, which may be dynamically created and destroyed by the GUI library. Below is cut & paste of some code I tested with your application. It works fine, except for the problem with quitting, which leaves the 4D environment in some kind of locked status. Debugging does not offer much information: all the active threads are from 4D and I do not have the sources of it. typedef struct { int pipe[2]; void *message; int integer; } comm_t; void comm_open(comm_t *c) { pipe(c->pipe); } void comm_close(comm_t *c) { close(c->pipe[0]); close(c->pipe[1]); } void * comm_read(comm_t *c) { char b; printf("Reading from pipe from %x\n", (int)pthread_self()); if (read(c->pipe[0], &b, sizeof(b)) < 0 || b != 0x13) return NULL; return c->message; } void comm_write(comm_t *c, void *message) { static const char b[1] = { 0x13 }; c->message = message; printf("Writing to pipe from %x\n", (int)pthread_self()); write(c->pipe[1], b, sizeof(*b)); } int comm_read_int(comm_t *c) { comm_read(c); return c->integer; } void comm_write_int(comm_t *c, int i) { c->integer = i; comm_write(c, &c->integer); } #define EMBED_ECL #ifdef EMBED_ECL static pthread_t ecl_thread; static comm_t slave_pipe[1]; static comm_t master_pipe[1]; static void * ecl_thread_entry(void *aux) { int argc = 1; char * argv[256]; cl_env_ptr env; argv[0] = ""; // cl_boot(argc, argv); printf("Entering slave thread\n"); GC_register_my_thread(argv); // This fixes a wrong initialization of GC_stackbottom // that only happens in OS X GC_stackbottom = (void*)(argv+255); ecl_set_option(ECL_OPT_TRAP_SIGSEGV, 0); ecl_set_option(ECL_OPT_TRAP_SIGFPE, 0); ecl_set_option(ECL_OPT_TRAP_SIGSEGV, 0); ecl_set_option(ECL_OPT_TRAP_SIGINT, 0); ecl_set_option(ECL_OPT_TRAP_SIGILL, 0); ecl_set_option(ECL_OPT_TRAP_SIGBUS, 0); ecl_set_option(ECL_OPT_TRAP_INTERRUPT_SIGNAL, 0); ecl_set_option(ECL_OPT_SIGNAL_HANDLING_THREAD, 0); ecl_set_option(ECL_OPT_INCREMENTAL_GC, 0); cl_boot(argc,argv); env = ecl_process_env(); // Lisp command loop CL_CATCH_ALL_BEGIN(env) { do { char *command = (char *)comm_read(slave_pipe); if (command) { cl_object c = c_string_to_object(command); printf("%s\n", command); cl_print(1,c); comm_write_int(master_pipe, ecl_length(c)); } else { break; } } while (1); } CL_CATCH_ALL_END; // Shut down ECL and remove links with garbage collector cl_shutdown(); GC_unregister_my_thread(); printf("Exited slave thread\n"); return NULL; } #endif // EMBED_ECL void InitPlugin() { #undef pthread_create #ifdef EMBED_ECL printf("Init thread: %p\n", (void*)pthread_self()); comm_open(slave_pipe); comm_open(master_pipe); pthread_create(&ecl_thread, NULL, ecl_thread_entry, NULL); printf("Finished initialization\n"); #endif } void DeinitPlugin() { #ifdef EMBED_ECL comm_write(slave_pipe, NULL); comm_close(slave_pipe); comm_close(master_pipe); printf("DeinitPlugin() exited\n"); #endif } -- Instituto de FĂsica Fundamental, CSIC c/ Serrano, 113b, Madrid 28006 (Spain) http://juanjose.garciaripoll.googlepages.com ------------------------------------------------------------------------------ The Palm PDK Hot Apps Program offers developers who use the Plug-In Development Kit to bring their C/C++ apps to Palm for a share of $1 Million in cash or HP Products. Visit us here for more details: http://p.sf.net/sfu/dev2dev-palm _______________________________________________ Ecls-list mailing list Ecls-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ecls-list