Merge remote branch 'jmarshall/dirtyregion_container_fix'
[vuplus_xbmc] / xbmc / threads / Condition.h
1 /*
2  *      Copyright (C) 2005-2011 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, write to
17  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21
22 #pragma once
23
24 #include "threads/platform/Condition.h"
25
26 #include "threads/SystemClock.h"
27 #include <stdio.h>
28
29 namespace XbmcThreads
30 {
31
32   /**
33    * This is a condition variable along with its predicate. This allows the use of a 
34    *  condition variable without the spurious returns since the state being monitored
35    *  is also part of the condition.
36    *
37    * L should implement the Lockable concept
38    *
39    * The requirements on P are that it can act as a predicate (that is, I can use
40    *  it in an 'while(!predicate){...}' where 'predicate' is of type 'P').
41    */
42   template <typename P> class TightConditionVariable
43   {
44     ConditionVariable& cond;
45     P predicate;
46
47   public:
48     inline TightConditionVariable(ConditionVariable& cv, P predicate_) : cond(cv), predicate(predicate_) {}
49
50     template <typename L> inline void wait(L& lock) { while(!predicate) cond.wait(lock); }
51     template <typename L> inline bool wait(L& lock, unsigned long milliseconds)
52     {
53       bool ret = true;
54       if (!predicate)
55       {
56         if (!milliseconds)
57         {
58           cond.wait(lock,milliseconds /* zero */);
59           return !(!predicate); // eh? I only require the ! operation on P
60         }
61         else
62         {
63           EndTime endTime((unsigned int)milliseconds);
64           for (bool notdone = true; notdone && ret == true;
65                ret = (notdone = (!predicate)) ? ((milliseconds = endTime.MillisLeft()) != 0) : true)
66             cond.wait(lock,milliseconds);
67         }
68       }
69       return ret;
70     }
71
72     inline void notifyAll() { cond.notifyAll(); }
73     inline void notify() { cond.notify(); }
74   };
75 }
76