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.