/*
- * Copyright (C) 2005-2011 Team XBMC
- * http://www.xbmc.org
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://xbmc.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with XBMC; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- * http://www.gnu.org/copyleft/gpl.html
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
*
*/
#pragma once
-#include <boost/thread/condition_variable.hpp>
+#include "threads/platform/Condition.h"
-#include "threads/SingleLock.h"
+#include "threads/SystemClock.h"
+#include <stdio.h>
namespace XbmcThreads
{
- /**
- * This is a thin wrapper around boost::condition_variable. It is subject
- * to "spurious returns" as it is built on boost which is built on posix
- * on many of our platforms.
- */
- class ConditionVariable
- {
- private:
- boost::condition_variable_any impl;
-
- // explicitly deny copying
- inline ConditionVariable(const ConditionVariable& other) {}
- inline ConditionVariable& operator=(ConditionVariable& other) { return *this; }
- public:
- inline ConditionVariable() {}
-
- enum TimedWaitResponse { TW_OK = 0, TW_TIMEDOUT = 1, TW_INTERRUPTED=-1, TW_ERROR=-2 };
-
- template<typename L> inline void wait(L& lock) { impl.wait(lock); }
-
- template<typename L> inline TimedWaitResponse wait(L& lock, int milliseconds)
- {
- ConditionVariable::TimedWaitResponse ret = TW_OK;
- try { ret = (impl.timed_wait(lock, boost::posix_time::milliseconds(milliseconds))) ? TW_OK : TW_TIMEDOUT; }
- catch (boost::thread_interrupted ) { ret = TW_INTERRUPTED; }
- catch (...) { ret = TW_ERROR; }
- return ret;
- }
-
- inline void notifyAll() { impl.notify_all(); }
- inline void notify() { impl.notify_one(); }
- };
/**
* This is a condition variable along with its predicate. This allows the use of a
*/
template <typename P> class TightConditionVariable
{
- ConditionVariable cond;
+ ConditionVariable& cond;
P predicate;
+
public:
- inline TightConditionVariable(P predicate_) : predicate(predicate_) {}
- template <typename L> inline void wait(L& lock) { while(!predicate) cond.wait(lock); }
+ inline TightConditionVariable(ConditionVariable& cv, P predicate_) : cond(cv), predicate(predicate_) {}
- template <typename L> inline ConditionVariable::TimedWaitResponse wait(L& lock, int milliseconds)
+ template <typename L> inline void wait(L& lock) { while(!predicate) cond.wait(lock); }
+ template <typename L> inline bool wait(L& lock, unsigned long milliseconds)
{
- ConditionVariable::TimedWaitResponse ret = ConditionVariable::TW_OK;
- boost::system_time const timeout=boost::get_system_time() + boost::posix_time::milliseconds(milliseconds);
- while ((!predicate) && ret != ConditionVariable::TW_TIMEDOUT)
+ bool ret = true;
+ if (!predicate)
{
- ret = cond.wait(lock,milliseconds);
-
- if (!predicate && boost::get_system_time() > timeout)
- ret = ConditionVariable::TW_TIMEDOUT;
+ if (!milliseconds)
+ {
+ cond.wait(lock,milliseconds /* zero */);
+ return !(!predicate); // eh? I only require the ! operation on P
+ }
+ else
+ {
+ EndTime endTime((unsigned int)milliseconds);
+ for (bool notdone = true; notdone && ret == true;
+ ret = (notdone = (!predicate)) ? ((milliseconds = endTime.MillisLeft()) != 0) : true)
+ cond.wait(lock,milliseconds);
+ }
}
return ret;
}