> > Personally, I completely disagree. It is very hard to
> > understand control
> > flow when all the state is hidden. You see a 'return' statement -- where
> > does that go? What if you want to log the state of a connection to
> > facilitate debugging? Hiding the state on the stack is not good
> practice.
> I don't entirely understand what you're saying -- is this a
> general argument
> against threads?
Umm, no. It's a general argument against storing connection state on the
stack.
> I thought the whole point of Pth was to store
> thread state
> on the stack...?
Yes. *THREAD* state. But thread state is "what am I doing right now", not
"what did I do in the past" or "what am I going to do in the future".
> Well, maybe it would help me understand if we used a
> concrete example:
> void *threadMain(void *_arg) {
> char inputBuff[BUFFLEN], moreInput[BUFFLEN];
> int client_fd = (int)_arg;
>
> pth_readline(client_fd, inputBuff, BUFLEN);
>
> if (strncmp(inputBuff, "GET ", 4) == 0) {
> <do some stuff>
> pth_write(client_fd, <response>);
> } else if (strncmp(inputBuff, "PUT ", 4) == 0) {
> pth_readline(client_fd, moreInput, BUFLEN);
> <do some stuff>
> pth_write(client_fd, <response>);
> }
> }
> Okay, so this is a really simple routine executed by worker threads to
> process a line or two of input from a client and send a response. Is this
> bad coding style? Would you do this with a single-threaded state
> machine of
> some sort? Or some other way?
This has two states, waiting for the first line and waiting for the second
line. So I'd tell my network I/O layer to go in line mode, and my
'ProcessLine' function would look like this:
void MyProtocol::ProcessLine(const char *data, int len)
{ // called when a line has been received
if(state==PRE_URL)
{
if(strncmp(data, "GET ", 4)==0)
{
<do some stuff>
Send(<response>); // Note: this puts data on the send
// queue and starts output if needed, it never blocks
if(NotDone) state=SENDING;
else state=COMPLETE;
}
else if(strncmp(data, "PUT ", 4)==0) {
state=DOING_PUT;
}
}
else if(state==DOING_PUT)
{
<do some stuff>
Send(<response>);
if(GotAllStuff) state=SENDING;
}
}
This is close to the actual code in 'crws', the web server that ships with
ConferenceRoom. It's a full HTTP implementation and has a grand total of 4
states:
1) Awaiting cmd/url/proto line
2) Receiving headers
3) Receiving POST data
4) Sending body
The network code takes care of the nitty-gritty of accepting connections,
managing send queues, and splitting input into lines. It's agressively
multi-threaded using thread pools and can easily handle thousands of
connections with dozens of threads.
DS
______________________________________________________________________
GNU Portable Threads (Pth) http://www.gnu.org/software/pth/
Development Site http://www.ossp.org/pkg/lib/pth/
Distribution Files ftp://ftp.gnu.org/gnu/pth/
Distribution Snapshots ftp://ftp.ossp.org/pkg/lib/pth/
User Support Mailing List [EMAIL PROTECTED]
Automated List Manager (Majordomo) [EMAIL PROTECTED]