blob: 463f52322325d81c5d724536853d769bc9583b61 [file] [log] [blame]
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Condition variables.
#ifndef STARBOARD_CONDITION_VARIABLE_H_
#define STARBOARD_CONDITION_VARIABLE_H_
#ifdef __cplusplus
#include <deque>
#endif
#include "starboard/export.h"
#include "starboard/mutex.h"
#include "starboard/thread_types.h"
#include "starboard/time.h"
#include "starboard/types.h"
#ifdef __cplusplus
extern "C" {
#endif
// Enumeration of possible results from waiting on a condvar.
typedef enum SbConditionVariableResult {
// The wait completed because the condition variable was signaled.
kSbConditionVariableSignaled,
// The wait completed because it timed out, and was not signaled.
kSbConditionVariableTimedOut,
// The wait failed, either because a parameter wasn't valid, or the condition
// variable has already been destroyed, or something similar.
kSbConditionVariableFailed,
} SbConditionVariableResult;
// Returns whether the given result is a success.
static SB_C_INLINE bool SbConditionVariableIsSignaled(
SbConditionVariableResult result) {
return result == kSbConditionVariableSignaled;
}
// Creates a new condition variable to work with |opt_mutex|, which may be null,
// placing the newly created condition variable in |out_condition|. Returns
// whether the condition variable could be created.
// TODO: It looks like WTF does not have the mutex available when creating
// the condition variable, and pthreads doesn't appear to require the mutex on
// condvar creation, so we should just remove the parameter.
SB_EXPORT bool SbConditionVariableCreate(SbConditionVariable* out_condition,
SbMutex* opt_mutex);
// Destroys a condition variable, returning whether the destruction was
// successful. The condition variable specified by |condition| is
// invalidated. Behavior is undefined if other threads are currently waiting
// on this condition variable.
SB_EXPORT bool SbConditionVariableDestroy(SbConditionVariable* condition);
// Waits for |condition|, releasing the held lock |mutex|, blocking
// indefinitely, and returning the result. Behavior is undefined if |mutex| is
// not held.
SB_EXPORT SbConditionVariableResult
SbConditionVariableWait(SbConditionVariable* condition, SbMutex* mutex);
// Waits for |condition|, releasing the held lock |mutex|, blocking up to
// |timeout_duration|, and returning the acquisition result. If
// |timeout_duration| is less than or equal to zero, it will return as quickly
// as possible with a kSbConditionVariableTimedOut result. Behavior is undefined
// if |mutex| is not held.
SB_EXPORT SbConditionVariableResult
SbConditionVariableWaitTimed(SbConditionVariable* condition,
SbMutex* mutex,
SbTime timeout_duration);
// Broadcasts to all current waiters of |condition| to stop waiting.
SB_EXPORT bool SbConditionVariableBroadcast(SbConditionVariable* condition);
// Signals the next waiter of |condition| to stop waiting.
SB_EXPORT bool SbConditionVariableSignal(SbConditionVariable* condition);
#ifdef __cplusplus
} // extern "C"
#endif
#ifdef __cplusplus
namespace starboard {
// Inline class wrapper for SbConditionVariable.
class ConditionVariable {
public:
explicit ConditionVariable(const Mutex& mutex)
: mutex_(mutex.mutex()), condition_() {
SbConditionVariableCreate(&condition_, mutex_);
}
~ConditionVariable() { SbConditionVariableDestroy(&condition_); }
void Wait() const { SbConditionVariableWait(&condition_, mutex_); }
bool WaitTimed(SbTime duration) const {
return SbConditionVariableIsSignaled(
SbConditionVariableWaitTimed(&condition_, mutex_, duration));
}
void Broadcast() const { SbConditionVariableBroadcast(&condition_); }
void Signal() const { SbConditionVariableSignal(&condition_); }
private:
mutable SbMutex* mutex_;
mutable SbConditionVariable condition_;
};
} // namespace starboard
#endif
#endif // STARBOARD_CONDITION_VARIABLE_H_