neuray API Programmer's Manual

condition.h File Reference

Description

Multithreading condition. See Multithreading Support.

Code Example

condition.h

‎/***************************************************************************************************
 * Copyright 2024 NVIDIA Corporation. All rights reserved.
 **************************************************************************************************/

#ifndef MI_BASE_CONDITION_H
#define MI_BASE_CONDITION_H

#include <mi/base/config.h>
#include <mi/base/types.h>

#ifndef MI_PLATFORM_WINDOWS
#include <cerrno>
#include <pthread.h>
#include <sys/time.h>
#else
#include <mi/base/miwindows.h>
#endif

namespace mi {

namespace base {


class Condition
{
public:
    Condition()
    {
#ifndef MI_PLATFORM_WINDOWS
        m_signaled = false;
        pthread_mutex_init( &m_mutex, NULL);
        pthread_cond_init( &m_condvar, NULL);
#else
        m_handle = CreateEvent( NULL, false, false, NULL);
#endif
    }

    ~Condition()
    {
#ifndef MI_PLATFORM_WINDOWS
        pthread_mutex_destroy( &m_mutex);
        pthread_cond_destroy( &m_condvar);
#else
        CloseHandle( m_handle);
#endif
    }

    void wait()
    {
#ifndef MI_PLATFORM_WINDOWS
        pthread_mutex_lock( &m_mutex);
        while( !m_signaled) //-V776 PVS
            pthread_cond_wait( &m_condvar, &m_mutex);
        m_signaled = false;
        pthread_mutex_unlock( &m_mutex);
#else
        WaitForSingleObject( m_handle, INFINITE);
#endif
    }

    bool timed_wait( Float64 timeout) {
#ifndef MI_PLATFORM_WINDOWS
        struct timeval now;
        gettimeofday( &now, NULL);
        struct timespec timeout_abs;
        timeout_abs.tv_sec = now.tv_sec + static_cast<long>( floor( timeout));
        timeout_abs.tv_nsec
            = 1000 * now.tv_usec + static_cast<long>( 1E9 * ( timeout - floor( timeout)));
        if( timeout_abs.tv_nsec > 1000000000) {
            timeout_abs.tv_sec  += 1;
            timeout_abs.tv_nsec -= 1000000000;
        }

        bool timed_out = false;
        pthread_mutex_lock( &m_mutex);
        while( !m_signaled)
        {
            int result = pthread_cond_timedwait( &m_condvar, &m_mutex, &timeout_abs);
            timed_out = result == ETIMEDOUT;
            if( result != EINTR)
                break;
        }
        m_signaled = false;
        pthread_mutex_unlock( &m_mutex);
        return timed_out;
#else
        DWORD timeout_ms = static_cast<DWORD>( 1000 * timeout);
        DWORD result = WaitForSingleObject( m_handle, timeout_ms);
        return result == WAIT_TIMEOUT;   
#endif    
    }

    void signal()
    {
#ifndef MI_PLATFORM_WINDOWS
        pthread_mutex_lock( &m_mutex);
        m_signaled = true;
        pthread_cond_signal( &m_condvar);
        pthread_mutex_unlock( &m_mutex);
#else
        SetEvent( m_handle);
#endif
    }

    void reset()
    {
#ifndef MI_PLATFORM_WINDOWS
        pthread_mutex_lock( &m_mutex);
        m_signaled = false;
        pthread_mutex_unlock( &m_mutex);
#else
        ResetEvent( m_handle);
#endif
    }

private:
#ifndef MI_PLATFORM_WINDOWS
    pthread_mutex_t m_mutex;
    pthread_cond_t m_condvar;
    bool m_signaled;
#else
    HANDLE m_handle;
#endif
};
 // end group mi_base_threads

} // namespace base

} // namespace mi

#endif // MI_BASE_CONDITION_H

Namespaces

namespace 
Common namespace for APIs of NVIDIA Advanced Rendering Center GmbH. More...
namespace 
Namespace for the Base API. More...

Classes

class 
Conditions allow threads to signal an event and to wait for such a signal, respectively. More...