0

I have the following code:

bool Mutex::timed_lock(unsigned long milliseconds)
{
    if (!milliseconds)
    {
        return lock();
    }

    struct timespec ts;
    ts.tv_sec = milliseconds / 1000;
    ts.tv_nsec = (milliseconds - (ts.tv_sec * 1000)) * 1000000;

    //printf("%lld, %ld\n\n", ts.tv_sec, ts.tv_nsec);


    int res = pthread_mutex_timedlock(&info->mutex, &ts);
    info->ref_count += res != ETIMEDOUT && res != EDEADLK && !res ? 1 : 0;
    return res != ETIMEDOUT && res != EDEADLK && !res;
}

then I tried testing it like so:

Mutex lock;

std::thread([&]{
    std::cout<<"LOCKED: "<<std::boolalpha<<lock.lock()<<"\n";
    Sleep(5000);
}).detach();
Sleep(1000);

std::cout<<"DONE: "<<std::boolalpha<<lock.timed_lock(6600)<<"\n";

The result is that it prints "LOCKED: true \n DONE: false" and ETIMEDOUT is the error. It's supposed to block for the duration of 6600 ms if it cannot lock it.

Any ideas what I'm doing wrong? I'm only reinventing the wheel instead of using the C++11 std::mutex because this Mutex I need to share for IPC synchronisation/events (similar to WinAPI's CreateEvent).

Brandon
  • 22,723
  • 11
  • 93
  • 186
  • Why not use `CreateMutex` ? This would avoid all these linux wrapper libraries... – ElderBug Feb 16 '15 at 08:53
  • Oh because I need to use it on Linux & OSX as well.. I just didn't want to bother with all the #ifdef's and stuff.. – Brandon Feb 16 '15 at 08:59

1 Answers1

3

The timeout to pthread_mutex_timedlock() is an absolute timeout, not a relative timeout. So you need to figure out the current time and calculate the future absolute time:

struct timespec ts;
struct timespec now;
gettimeofday(&now, NULL);
ts->tv_sec = now.tv_sec + milliseconds/1000;
ts->tv_nsec = (now.tv_usec * 1000) + ((milliseconds%1000) * 1000000);
if (ts.tv_nsec >= 1000000000) {
     ts.tv_sec++;
     ts.tv_nsec -= 1000000000;
}
nos
  • 223,662
  • 58
  • 417
  • 506