Picture this:
ChiliMoon 2004, http.pike uses the Shuffler object.
It works fine (after a few modifications to the do_log callback),
except when I call up a CGI program.
cgi.pike uses a wrapper that uses a pair of pipes to pass the data
along.
Now, doing an add_source for shuffler with the proper end of the pipe,
will result in the pipe being read correctly (once, total amount read,
no followup read that should have detected the end).
After that, the content of that read() is lost.
Trying something different, I add three add_source() calls before,
and three add_source() calls after the add_source() for the pipe.
The three preceding and trailing add_source() calls have a fixed string
content.
What happens now is:
Shuffle[0x9c98b00]:add_source(XX,0,-1) --> 0x9081d48 <<-- const string
Shuffle[0x9c98b00]:add_source(XX,0,-1) --> 0x9f64770 <<-- const string
Shuffle[0x9c98b00]:add_source(XX,0,-1) --> 0x9c45038 <<-- const string
Shuffle[0x9c98b00]:add_source(XX,0,-1) --> 0x9f5d690 <<-- pipe
Shuffle[0x9c98b00]:add_source(XX,0,-1) --> 0x9c45068 <<-- const string
Shuffle[0x9c98b00]:add_source(XX,0,-1) --> 0x9c45098 <<-- const string
Shuffle[0x9c98b00]:add_source(XX,0,-1) --> 0x9c988c8 <<-- const string
Shuffle[0x9c98b00]:set_done_callback(0x8d0141c)
Shuffle[0x9c98b00]:start()
Shuffle[0x9c98b00]:_set_callbacks()
Shuffle[0x9c98b00]:__set_calllbacks(Pike)
...CGIWrapper is being done...
Shuffle[0x9c98b00]:write_callback()
Shuffle[0x9c98b00]:_send_more(0)
Shuffle[0x9c98b00]:_request(8192) from (nil)
Shuffle[0x9c98b00]:__send_more_callback(8192)
Shuffle[0x9c98b00]:__send_more_callback(): sending(48)
Shuffle[0x9c98b00]:__send_more_callback(): sending(48): sent 48
Shuffle[0x9c98b00]:_give_back(8144)
Shuffle[0x9c98b00]:write_callback()
Shuffle[0x9c98b00]:_send_more(0)
Shuffle[0x9c98b00]:_request(8192) from (nil)
Shuffle[0x9c98b00]:__send_more_callback(8192)
Shuffle[0x9c98b00]:__send_more_callback(): source done: 0x9081d48
Shuffle[0x9c98b00]:__send_more_callback(): sending(46)
Shuffle[0x9c98b00]:__send_more_callback(): sending(46): sent 46
Shuffle[0x9c98b00]:_give_back(8146)
Shuffle[0x9c98b00]:write_callback()
Shuffle[0x9c98b00]:_send_more(0)
Shuffle[0x9c98b00]:_request(8192) from (nil)
Without the patch attached below, the argument to __send_more_callback
becomes -2 (from the leftovers.len), and the program crashes with a
SEGV shortly after removing the callbacks.
With the patch, the following happens:
Shuffle[0x9c98b00]:__send_more_callback(8192)
Shuffle[0x9c98b00]:__send_more_callback(): source done: 0x9c45038
Shuffle[0x9c98b00]:__send_more_callback(): read pending
Shuffle[0x9c98b00]:__remove_calllbacks(Pike)
Shuffle[0x9c98b00]:_give_back(8192)
Shuffle[0x9c98b00]:_set_callbacks()
Shuffle[0x9c98b00]:__set_calllbacks(Pike)
However, at this point: - Data has been read from the CGIWrapper
- But no trace of that appears in the output
- I.e. in the output the six constant strings
simply stick together.
Shuffle[0x9c98b00]:write_callback()
Shuffle[0x9c98b00]:_send_more(0)
Shuffle[0x9c98b00]:_request(8192) from (nil)
Shuffle[0x9c98b00]:__send_more_callback(8192)
Shuffle[0x9c98b00]:__send_more_callback(): source done: 0x9f5d690
Shuffle[0x9c98b00]:__send_more_callback(): sending(17)
Shuffle[0x9c98b00]:__send_more_callback(): sending(17): sent 17
Shuffle[0x9c98b00]:_give_back(8175)
Shuffle[0x9c98b00]:write_callback()
Shuffle[0x9c98b00]:_send_more(0)
Shuffle[0x9c98b00]:_request(8192) from (nil)
Shuffle[0x9c98b00]:__send_more_callback(8192)
Shuffle[0x9c98b00]:__send_more_callback(): source done: 0x9c45068
Shuffle[0x9c98b00]:__send_more_callback(): sending(16)
Shuffle[0x9c98b00]:__send_more_callback(): sending(16): sent 16
Shuffle[0x9c98b00]:_give_back(8176)
Shuffle[0x9c98b00]:write_callback()
Shuffle[0x9c98b00]:_send_more(0)
Shuffle[0x9c98b00]:_request(8192) from (nil)
Shuffle[0x9c98b00]:__send_more_callback(8192)
Shuffle[0x9c98b00]:__send_more_callback(): source done: 0x9c45098
Shuffle[0x9c98b00]:__send_more_callback(): sending(15)
Shuffle[0x9c98b00]:__send_more_callback(): sending(15): sent 15
Shuffle[0x9c98b00]:_give_back(8177)
Shuffle[0x9c98b00]:write_callback()
Shuffle[0x9c98b00]:_send_more(0)
Shuffle[0x9c98b00]:_request(8192) from (nil)
Shuffle[0x9c98b00]:__send_more_callback(8192)
Shuffle[0x9c98b00]:__send_more_callback(): source done: 0x9c988c8
Shuffle[0x9c98b00]:__send_more_callback(): no sources
Shuffle[0x9c98b00]:_give_back(8192)
Shuffle[0x9c98b00]:_all_done(0)
Shuffle[0x9c98b00]:_all_done(0): Calling done callback: 0x8d0141c
Shuffle[0x9c98b00]:sent_data() --> 189
Shuffle[0x9c98b00]:_remove_callbacks()
Shuffle[0x9c98b00]:__remove_calllbacks(Pike)
Shuffle[0x9c98b00]:exit()
Now, besides this patch, which prevents it from segfaulting,
I'm a bit lost now. The shuffler innards are a maze of twists, turns
and callbacks. I must be close, but the non-linear program flow is
difficult to decipher.
--
Sincerely, srb(a)cuci.nl
Stephen R. van den Berg (AKA BuGless).
"Very funny, Mr. Scott. Now beam down my clothes!"