/****************************************************************************
 *  INTEL CONFIDENTIAL
 *  Copyright 2006 Intel Corporation All Rights Reserved.
 *
 *  The source code contained or described herein and all documents related
 *  to the source code ("Material") are owned by Intel Corporation or its
 *  suppliers or licensors. Title to the Material remains with Intel
 *  Corporation or its suppliers and licensors. The Material may contain
 *  trade secrets and proprietary and confidential information of Intel
 *  Corporation and its suppliers and licensors, and is protected by
 *  worldwide copyright and trade secret laws and treaty provisions. No part
 *  of the Material may be used, copied, reproduced, modified, published,
 *  uploaded, posted, transmitted, distributed, or disclosed in any way
 *  without Intel's prior express written permission.
 *
 *  No license under any patent, copyright, trade secret or other
 *  intellectual property right is granted to or conferred upon you by
 *  disclosure or delivery of the Materials, either expressly, by
 *  implication, inducement, estoppel or otherwise. Any license under such
 *  intellectual property rights must be express and approved by Intel in
 *  writing.
 *
 *  Unless otherwise agreed by Intel in writing, you may not remove or alter
 *  this notice or any other notice embedded in Materials by Intel or Intel's
 *  suppliers or licensors in any way.
 ****************************************************************************/

/****************************************************************************
 * Description: Describes condition variables (or events, as Windows calls
 *              them).
 ****************************************************************************/

#ifndef COMPAT_COND_
#define COMPAT_COND_

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#include <pthread.h>

#include "compat_lib.h"
#include "compat_time.h"

/****************************************************************************
 * Name:        struct priv_CPL_Cond
 * Description: Encapsulates the contents of the CPL_Cond data type, which
 *              contains the handles for two Events.
 * NOTE: This structure is architecture-dependent. DON'T USE ITS CONTENTS.
 ****************************************************************************/
struct priv_CPL_Cond {
    pthread_cond_t cond;   /* The condition variable */
    pthread_mutex_t mutex; /* The mutex that pthread_cond_timedwait requires */
};

typedef struct priv_CPL_Cond CPL_Cond;


/****************************************************************************
 *  Function:    CPL_CondInit
 *  Description: Initializes a condition variable for later use.
 *  Parameters:  cond   [OUT] A pointer to the condition variable to init.
 *  Returns:     Zero on success, or a CPL_GetError() code on failure.
 ****************************************************************************/
INT32U CPL_CondInit(CPL_Cond * cond);

/****************************************************************************
 *  Function:    CPL_CondWait
 *  Description: Waits indefinitely for a condition variable to be signaled.
 *  Parameters:
 *    cond   [IN] The condition variable on which to await a signal.
 *  Returns:     Zero on success, or a CPL_GetError() code on failure.
 ****************************************************************************/
INT32U CPL_CondWait(CPL_Cond * cond);

/****************************************************************************
 *  Function:    CPL_CondAbsTimedWait
 *  Description: Waits for a condition variable to be signaled, with an upper
 *               limit on how long to wait defined in absolute time.
 *  Parameters:  
 *    cond    [IN] The condition variable on which to await a signal.
 *    abstime [IN] The time to give up on waiting for the condition variable.
 *  Returns:     Zero on success, or a CPL_GetError() code on failure.
 ****************************************************************************/
INT32U CPL_CondAbsTimedWait(CPL_Cond                  * cond,
                            const struct CPL_TimeSpec * abstime);

/****************************************************************************
 *  Function:    CPL_CondRelTimedWait
 *  Description: Waits for a condition variable to be signaled, with an upper
 *               limit on how long to wait defined relative to current time.
 *  Parameters:  
 *    cond     [IN] The condition variable on which to await a signal.
 *    interval [IN] How long to wait for the condition variable.
 *  Returns:     Zero on success, or a CPL_GetError() code on failure.
 ****************************************************************************/
INT32U CPL_CondRelTimedWait(CPL_Cond                  * cond,
                                       const struct CPL_TimeSpec * interval);

/****************************************************************************
 *  Function:    CPL_CondSignal
 *  Description: Awakens exactly one of the waiting threads.
 *  Parameters:  cond   [IN] The condition variable to signal.
 *  Returns:     Zero on success, or a CPL_GetError() code on failure.
 ****************************************************************************/
INT32U CPL_CondSignal(CPL_Cond * cond);

/****************************************************************************
 *  Function:    CPL_CondBroadcast
 *  Description: Awakens all of the waiting threads.
 *  Parameters:  cond   [IN] The condition variable to signal.
 *  Returns:     Zero on success, or a CPL_GetError() code on failure.
 ****************************************************************************/
INT32U CPL_CondBroadcast(CPL_Cond * cond);

/****************************************************************************
 *  Function:    CPL_CondDestroy
 *  Description: Destroys a condition variable and frees all its resources.
 *  Parameters:  cond   [IN] The condition variable to destroy.
 *  Returns:     Zero on success, or a CPL_GetError() code on failure.
 ****************************************************************************/
INT32U CPL_CondDestroy(CPL_Cond * cond);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* COMPAT_COND_ */
