Waiting for a thread.. (pthread_join with timeout)

0 comments

I recently found myself needing a way to wait for a thread to complete without blocking indefinitely in the case that the waitee runs indefinitely. So i thought, hey I'll just call wait_with_timeout (or whatever pthreads calls it), and I'll be set. In win32 they have this, it's implemented via the ubiquitous WaitForSingleObject(), and you just pass the thread handle and a timeout.

Well, the only problem is that pthreads just doesn't have this api. Only thing (that I can find), is pthread_join(). This will however, block the calling thread until the waitee finishes, or the calling thread is pthread_cancel()ed. So I started thinking about what I can do to implement something like the WaitForSingleObject() behavior, and this is what I came up with:


#include <stdio.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/select.h>

#define PTHREAD_JOIN_POLL_INTERVAL 10
#define false 0
#define true (!false)

typedef struct _waitData waitData;

struct _waitData
{
pthread_t waitID;
pthread_t helpID;
int done;
};

void
sleep_msecs(int msecs)
{
struct timeval tv;

tv.tv_sec = msecs/1000;
tv.tv_usec = (msecs % 1000) * 1000;
select (0,NULL,NULL,NULL,&tv);
}
unsigned int
get_ticks()
{
struct timeval tv;

gettimeofday(&tv, NULL);
return (tv.tv_usec/1000 + tv.tv_sec * 1000);
}

void *
join_timeout_helper(void *arg)
{
waitData *data = (waitData*)arg;

pthread_join(data->waitID, NULL);
data->done = true;
return (void *)0;
}

int
pthread_join_timeout(pthread_t wid, int msecs)
{
pthread_t id;
waitData data;
unsigned int start = get_ticks();
int timedOut = false;

data.waitID = wid;
data.done = false;

if (pthread_create(&id, NULL, join_timeout_helper, &data) != 0)
return (-1);
do {
if (data.done)
break;
/* you could also yield to your message loop here... */
sleep_msecs(PTHREAD_JOIN_POLL_INTERVAL);
} while ((get_ticks() - start) < msecs);
if (!data.done)
{
pthread_cancel(id);
timedOut = true;
}
/* free helper thread resources */
pthread_join(id, NULL);
return (timedOut);
}


It seems like a lot of effort for what I'm getting in return, but it seems to work pretty well. I'm a little bit concerned about the overhead of spinning off a new thread to handle this, but at least on Linux this is (fairly) cheap. The code runs on OS X without modification as well.


Happiness is a warm...

0 comments

Oh wait. I spent a few hours today dinking with Xcode and the so called 10.1.5 SDK. That is what I call a serious joke.

The first issue:

#include <sys/poll.h>


Apple has a bug in their legacy SDK in that they fail to include this header, and the related library (yes, there appears to be a separate library for poll. Whatever.). So, I'm moving to the land of oh joy private copies of system headers and run time linking. Laaaame.


About me

Last posts

Archives

Links


    ATOM 0.3