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

Another threading question



I'm still having some trouble working with threads from within
C.  Here's the rough flow of the program, along with bits from the
server log to illustrate:

1.  An HTTP request comes in for a scheme script.  The contents of the
file are read from disk (the first time), read into a Scheme input
port, compiled to bytecode, and then stored (in string form) for
later use.

[11/Jan/2001:21:24:47][3074.6151][-conn0-] Debug: MV_PageGet: url /test.ss
[11/Jan/2001:21:24:47][3074.6151][-conn0-] Debug: MachV: Loading "/var/www/Fulghams/www/test.ss" from disk
[11/Jan/2001:21:24:47][3074.6151][-conn0-] Debug: Internal String: (begin(begin
(display "Content-type: text/html")
(newline)
(newline)
(display "<HTML><HEAD>")
(display "<TITLE>Big Fun Test</TITLE>")
(display "<BODY><H1>Another Exciting Moment</H1>")
(display "Another Great Test!")
(display "<B>")
(display "Did I work?")
(display "</HTML>"))
)
[11/Jan/2001:21:24:47][3074.6151][-conn0-] Debug: Waiting for completion
[11/Jan/2001:21:24:47][3074.4101][MachV Intrp Svr] Debug: MachV:  Must compile string to a thunk.
[11/Jan/2001:21:24:47][3074.4101][MachV Intrp Svr] Debug: MachV: Here it is: #`ý^_^A, len=294
[11/Jan/2001:21:24:47][3074.4101][MachV Intrp Svr] Debug: MV_out_buffer::<create-type>
[11/Jan/2001:21:24:47][3074.4101][MachV Intrp Svr] Debug: MV_out_buffer: Initializing values
[11/Jan/2001:21:24:47][3074.4101][MachV Intrp Svr] Debug: AOLbuffer: Class constructor
[11/Jan/2001:21:24:47][3074.4101][MachV Intrp Svr] Debug: AOLbuffer: Initializing values
[11/Jan/2001:21:24:47][3074.4101][MachV Intrp Svr] Debug: MV_out_buffer::gOutputPort
[11/Jan/2001:21:24:47][3074.4101][MachV Intrp Svr] Notice: MachV:  Handle a request...

2.  An exception handling thunk (that calls-back to C when it
finishes evaluating) is created:

static char* exn_thunk =
 "(#%lambda (thunk) "
    "(mv-special-signal (current-thread)"
        "(#%with-handlers ([#%void (#%lambda (exn) (#%cons #f exn))]) "
			        	"(#%cons #t (thunk)))))";

"mv-special-signal" passes the thread ID and the result of the
evaluation back to C when finished.

[11/Jan/2001:21:24:47][3074.4101][MachV Intrp Svr] Debug: Apply thunk/catch-excn (Enter)
[11/Jan/2001:21:24:47][3074.4101][MachV Intrp Svr] Debug: Init_exn_catching
[11/Jan/2001:21:24:47][3074.4101][MachV Intrp Svr] Debug: Creating thunk.
[11/Jan/2001:21:24:47][3074.4101][MachV Intrp Svr] Debug: Init_exn_catching (Exit)
[11/Jan/2001:21:24:47][3074.4101][MachV Intrp Svr] Debug: do_eval

3.  I create the new thread (for the request) like this:

Scheme_Object* thrd_id = scheme_thread(
  _scheme_apply(exn_catching_apply, 1, &thunk), NULL);

Which applies the wrapper code from #2 (above) to the compiled
thunk.

The main thread then continues and stores the value of thrd_id
for later use.  Or, at least that's the theory.

In practice, the new thread runs merrily along, producing all the
output it should, jumping into the "mv-special-signal" as
expected with the thread ID and result.  However it segfaults at
this point (or I suspect, it segfaults once the thread finishes
running):

[11/Jan/2001:21:24:47][3074.4101][MachV Intrp Svr] Debug: AOLbuffer::write
[11/Jan/2001:21:24:47][3074.4101][MachV Intrp Svr] Debug: AOLbuffer: About to write string: Content-type: text/html

[ ... snip ... ]

[11/Jan/2001:21:36:51][3169.4101][MachV Intrp Svr] Debug: AOLbuffer: About to write string: </HTML>
[11/Jan/2001:21:36:51][3169.4101][MachV Intrp Svr] Debug: AOLbuffer: Putting message.
[11/Jan/2001:21:36:51][3169.4101][MachV Intrp Svr] Debug: Special-signal: The thread ID is 1076686876
[11/Jan/2001:21:36:51][3169.4101][MachV Intrp Svr] Debug: Init_exn_catching
[11/Jan/2001:21:36:51][3169.4101][MachV Intrp Svr] Debug: Creating thunk.
[11/Jan/2001:21:36:51][3169.4101][MachV Intrp Svr] Debug: Init_exn_catching (Exit)
[11/Jan/2001:21:36:51][3169.4101][MachV Intrp Svr] Debug: No return value.

Program received signal SIGSEGV, Segmentation fault.
Switching to Thread 4101 (LWP 3176)]
(gdb) 
0x4022f88e in is_stack_too_shallow2 () at ./process.c:1610
1610      scheme_check_stack_ok(s);
(gdb) bt
#0  0x4022f88e in is_stack_too_shallow2 () at ./process.c:1610
#1  0x4022f8b5 in is_stack_too_shallow () at ./process.c:1620
#2  0x4022f927 in scheme_thread_w_manager (thunk=0x4034e7e8, config=0x0, 
    mgr=0x0) at ./process.c:1669
#3  0x4022f71e in scheme_thread (thunk=0x4034e7e8, config=0x0)
    at ./process.c:1525
#4  0x40200915 in handle_request (request=0x8150278) at mv_interps.cc:285
#5  0x40200bb2 in Run (arg=0x8161e20) at mv_interps.cc:353
#6  0x811910b in NsThreadMain ()
#7  0x4002cce5 in pthread_start_thread () from /lib/libpthread.so.0
#8  0x4002cd2d in pthread_start_thread_event () from /lib/libpthread.so.0
(gdb) p s
Cannot access memory at address 0xbf1f9828

So, somehow I'm screwing up the stack.  Am I passing it some kind
of incomplete environment?

At any rate, it seems almost like the call to scheme_thread doesn't
really create a new thread to execute the thunk, since it doesn't
print out a mark point that would indicate that processing continues
in the main thread.

I'm getting close to getting it to work, but it's not quite there
yet....

Help!

Thanks,

-Brent