简体   繁体   中英

sem_timedwait Fails at Random

I've written a small class that encapsulates shared locks and shared semaphores. These classes pass all of my unit tests, except for one: about 60% of the time locking a shared memory semaphore using sem_timedwait fails. Here's my code:

SharedLock::SharedLock(const SharedSemaphore& semaphore, unsigned int wait_ns) :
    Succeeded(false),
    Semaphore(semaphore)
{
    timespec wait;
    if(clock_gettime(CLOCK_REALTIME, &wait) < 0)
    {
        throw exception_ty(SHARED_LOCK_RUNTIME_ERROR,
            "SharedLock::SharedLock(...) failed: clock_gettime(...) encountered an error.");
    }

    unsigned long ns = wait_ns % 1000000000;
    wait.tv_sec += (wait_ns - ns) / 1000000000;
    wait.tv_nsec += ns;
    int result = sem_timedwait(const_cast<sem_t*>(Semaphore.Semaphore.get_data()), &wait);

    if(result < 0 && errno != ETIMEDOUT)
    {
        throw_on_sem_wait();
    }

    else if(result == 0)
    {
        Succeeded = true;
    }
}

I am able to lock and unlock this semaphore without any errors using sem_wait and sem_trywait; only sem_timedwait fails randomly. When it fails it always sets errno to EINVAL. I am running these tests on Ubuntu Linux 12.10 (64 bit).

Could anyone suggest why I am having these problems, and how I may solve them?

EINVAL is returned either if sem is not a livad semaphore, or the value of abs_timeout.tv_nsecs is less than 0, or greater than or equal to 1000 million.

In your case sem should be a valid one, so the possible reason is that the wait.tv_nsec exceeds 1000 million, because it looks possible for the code wait.tv_nsec += ns; does not check the value.

You could print its value for debugging purpose, to see if it's the root cause.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM