> >     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]

Reply via email to