[OT] This feels wrong (pthreads question)

Steve smorrey at gmail.com
Sun Jan 28 14:22:10 MST 2007


Hi everyone,
As a coding excersize just to "see if I could do it" I decided to make
a chat server using UDP.
A major part of my design is the ability to scale up without slowing
down much, as such I decided to break my server design into 3 major
component objects.
Listener, Sender, Core.

The listener is pretty simple we just create a non blocking listener
on a port and poll it periodically.

The Core server design handles processing of information coming in
from the listener, i.e. reading the buffer, and creating new sender
objects if the client has never been seen before, as well as cleaning
up sender objects if the client has gone too long without a response.

The Sender(s) are where I'm having difficulty here, but it seems to me
this shouldn't be so hard.  Basically a sender is a self contained
"machine", it needs its own thread because it runs in an infinite loop
checking the main chat buffer in the Core, if anything has changed it
sends those changes to the client, and then sleeps for 250ms.

Now I know in a typical implementation, that all clients are contained
in a list and when the buffer has changed then the server iterates
through all the clients and sends out the changes.   But I don't
really like that design, the whole point of my design is to do it
without iterating through a list.

So as I was saying basically the sender class has a public method
called "void run()", this method is the function that wakes up, checks
the buffer, sends if needed and then goes back to sleep.

The problem is that pthreads won't allow me to call the member
function of an object.

I have tried placing it in the constructor, as well as outside of the
constructor.

<my original try in constructor>
Construct(){
      pthread_t t;
      pthread_create( &t, 0,run);
}
</end try>

<mysecond try>
Sender sender = new Sender;
      pthread_t t;
      pthread_create( &t, 0,sender->run);
</end my second try>

Neither of these worked at all so finally I re-created it as a new non
member, non friend function.

void runObject(void *data)
{
    Sender* sender = static_cast<Sender*>(data);
    //dosomething
    usleep(2500);
    runObject(data);
}

Now my code looks like
<my third try>
Sender* Client = new Sender(messageIP.c_str(), mI_port);
pthread_t t;
pthread_create( &t, 0,runObject, (void*)Client);
</end third try>

And it works, but it feels very wrong to me.  Having to cast the
object to void, then recast back to it's original form, seems like a
lot of overhead as well as being dangerous.  And it has to occur every
250 ms, which seems like alot of recasting to me.

So I'm wondering if anyone here has any ideas, I mean this should be a
real simple concept.

#1 Create new object which is self contained.
#2 spawn new thread
#3 check for updates
#4 sleep
#5 goto 3

Thoughts?  Ideas? Concerns?
Thanks in advance!



More information about the PLUG mailing list