Skip to content
This repository
Browse code

Merge pull request #3145 from jimfcarroll/removexp

Remove the Xp specific threading code.
  • Loading branch information...
commit bcf99dc264c6a8b9b91ab625b9f92b5bfe04e3bb 2 parents 2b2e2d1 + 331c04e
Martijn Kaijser authored August 31, 2013
1  project/VS2010Express/XbmcThreads.vcxproj
@@ -19,7 +19,6 @@
19 19
     <ClInclude Include="..\..\xbmc\threads\platform\win\ThreadImpl.cpp" />
20 20
     <ClInclude Include="..\..\xbmc\threads\platform\ThreadImpl.cpp" />
21 21
     <ClCompile Include="..\..\xbmc\threads\platform\Implementation.cpp" />
22  
-    <ClInclude Include="..\..\xbmc\threads\platform\win\Implementation.cpp" />
23 22
     <ClCompile Include="..\..\xbmc\threads\platform\win\Win32Exception.cpp" />
24 23
     <ClCompile Include="..\..\xbmc\threads\SystemClock.cpp" />
25 24
     <ClCompile Include="..\..\xbmc\threads\Thread.cpp" />
3  project/VS2010Express/XbmcThreads.vcxproj.filters
@@ -58,9 +58,6 @@
58 58
     <ClInclude Include="..\..\xbmc\threads\platform\ThreadImpl.cpp">
59 59
       <Filter>platform</Filter>
60 60
     </ClInclude>
61  
-    <ClInclude Include="..\..\xbmc\threads\platform\win\Implementation.cpp">
62  
-      <Filter>platform\win</Filter>
63  
-    </ClInclude>
64 61
     <ClInclude Include="..\..\xbmc\threads\platform\win\Win32Exception.h">
65 62
       <Filter>platform\win</Filter>
66 63
     </ClInclude>
26  xbmc/threads/Lockables.h
@@ -63,21 +63,31 @@ namespace XbmcThreads
63 63
 
64 64
     /**
65 65
      * This implements the "exitable" behavior mentioned above.
  66
+     *
  67
+     * This can be used to ALMOST exit, but not quite, by passing
  68
+     *  the number of locks to leave. This is used in the windows
  69
+     *  ConditionVariable which requires that the lock be entered
  70
+     *  only once, and so it backs out ALMOST all the way, but
  71
+     *  leaves one still there.
66 72
      */
67  
-    inline unsigned int exit() 
  73
+    inline unsigned int exit(unsigned int leave = 0) 
68 74
     { 
69 75
       // it's possibe we don't actually own the lock
70 76
       // so we will try it.
71 77
       unsigned int ret = 0;
72 78
       if (try_lock())
73 79
       {
74  
-        ret = count - 1;  // The -1 is because we don't want 
75  
-                          //  to count the try_lock increment.
76  
-        // We must NOT compare "count" in this loop since 
77  
-        // as soon as the last unlock is called another thread
78  
-        // can modify it.
79  
-        for (unsigned int i = 0; i <= ret; i++) // This will also unlock the try_lock.
80  
-          unlock();
  80
+        if (leave < (count - 1))
  81
+        {
  82
+          ret = count - 1 - leave;  // The -1 is because we don't want 
  83
+                                    //  to count the try_lock increment.
  84
+          // We must NOT compare "count" in this loop since 
  85
+          // as soon as the last unlock is called another thread
  86
+          // can modify it.
  87
+          for (unsigned int i = 0; i < ret; i++)
  88
+            unlock();
  89
+        }
  90
+        unlock(); // undo the try_lock before returning
81 91
       }
82 92
 
83 93
       return ret; 
2  xbmc/threads/platform/Implementation.cpp
@@ -20,6 +20,4 @@
20 20
 
21 21
 #if (defined TARGET_POSIX)
22 22
 #include "threads/platform/pthreads/Implementation.cpp"
23  
-#elif (defined TARGET_WINDOWS)
24  
-#include "threads/platform/win/Implementation.cpp"
25 23
 #endif
237  xbmc/threads/platform/win/Condition.h
@@ -27,227 +27,46 @@
27 27
 
28 28
 namespace XbmcThreads
29 29
 {
30  
-  class ConditionVariable;
31  
-  
32  
-  namespace intern
  30
+  /**
  31
+   * This is condition variable implementation that uses the underlying
  32
+   *  Windows mechanisms and assumes Vista (or later)
  33
+   */
  34
+  class ConditionVariable : public NonCopyable
33 35
   {
34  
-    /**
35  
-     * ConditionVariableXp is effectively a condition variable implementation
36  
-     *  assuming we're on Windows XP or earlier. This means we don't have 
37  
-     *  access to InitializeConditionVariable and that the structure 
38  
-     *  CONDITION_VARIABLE doesnt actually exist.
39  
-     *
40  
-     * This code is basically copied from SDL_syscond.c but structured to use 
41  
-     * native windows threading primitives rather than other SDL primitives.
42  
-     */
43  
-    class ConditionVariableXp : public NonCopyable
44  
-    {
45  
-      friend class ConditionVariable;
46  
-      CCriticalSection lock;
47  
-      int waiting;
48  
-      int signals;
49  
-
50  
-      class Semaphore
51  
-      {
52  
-        friend class ConditionVariableXp;
53  
-        HANDLE sem;
54  
-        volatile LONG count;
55  
-
56  
-        inline Semaphore() : count(0L), sem(NULL) {  }
57  
-        inline ~Semaphore() { if (sem) CloseHandle(sem); }
58  
-
59  
-        inline void Init() { sem = CreateSemaphore(NULL,0,32*1024,NULL); }
60  
-
61  
-        inline bool wait(DWORD dwMilliseconds)
62  
-        {
63  
-          return (WAIT_OBJECT_0 == WaitForSingleObject(sem, dwMilliseconds)) ?
64  
-            (InterlockedDecrement(&count), true) : false;
65  
-        }
66  
-
67  
-        inline bool post()
68  
-        {
69  
-          /* Increase the counter in the first place, because
70  
-           * after a successful release the semaphore may
71  
-           * immediately get destroyed by another thread which
72  
-           * is waiting for this semaphore.
73  
-           */
74  
-          InterlockedIncrement(&count);
75  
-          return ReleaseSemaphore(sem, 1, NULL) ? true : (InterlockedDecrement(&count), false);
76  
-        }
77  
-      };
78  
-
79  
-      Semaphore wait_sem;
80  
-      Semaphore wait_done;
81  
-
82  
-      inline ConditionVariableXp() : waiting(0), signals(0) { }
83  
-      inline ~ConditionVariableXp() {}
84  
-
85  
-      inline void Init() { wait_sem.Init(); wait_done.Init(); }
86  
-
87  
-      inline void wait(CCriticalSection& mutex) 
88  
-      {
89  
-        wait(mutex,(unsigned long)-1L);
90  
-      }
91  
-
92  
-      inline bool wait(CCriticalSection& mutex, unsigned long milliseconds) 
93  
-      { 
94  
-        bool success = false;
95  
-        DWORD ms = ((unsigned long)-1L) == milliseconds ? INFINITE : (DWORD)milliseconds;
96  
-
97  
-        {
98  
-          CSingleLock l(lock);
99  
-          waiting++;
100  
-        }
101  
-
102  
-        {
103  
-          CSingleExit ex(mutex);
104  
-          success = wait_sem.wait(ms);
105  
-
106  
-          {
107  
-            CSingleLock l(lock);
108  
-            if (signals > 0)
109  
-            {
110  
-              if (!success)
111  
-                wait_sem.wait(INFINITE);
112  
-              wait_done.post();
113  
-              --signals;
114  
-            }
115  
-            --waiting;
116  
-          }
117  
-        }
118  
-
119  
-        return success;
120  
-      }
121  
-
122  
-
123  
-      inline void wait(CSingleLock& lock) { wait(lock.get_underlying()); }
124  
-      inline bool wait(CSingleLock& lock, unsigned long milliseconds) { return wait(lock.get_underlying(), milliseconds); }
125  
-
126  
-      inline void notifyAll()
127  
-      {
128  
-        /* If there are waiting threads not already signalled, then
129  
-           signal the condition and wait for the thread to respond.
130  
-        */
131  
-        CSingleLock l(lock);
132  
-        if ( waiting > signals ) 
133  
-        {
134  
-          int i, num_waiting;
135  
-
136  
-          num_waiting = (waiting - signals);
137  
-          signals = waiting;
138  
-          for ( i=0; i<num_waiting; ++i )
139  
-            wait_sem.post();
140  
-
141  
-          /* Now all released threads are blocked here, waiting for us.
142  
-             Collect them all (and win fabulous prizes!) :-)
143  
-          */
144  
-          l.Leave();
145  
-          for ( i=0; i<num_waiting; ++i )
146  
-            wait_done.wait(INFINITE);
147  
-        }
148  
-      }
  36
+    CONDITION_VARIABLE cond;
149 37
 
150  
-      inline void notify()
151  
-      {
152  
-        /* If there are waiting threads not already signalled, then
153  
-           signal the condition and wait for the thread to respond.
154  
-        */
155  
-        CSingleLock l(lock);
156  
-        if ( waiting > signals ) 
157  
-        {
158  
-          ++signals;
159  
-          wait_sem.post();
160  
-          l.Leave();
161  
-          wait_done.wait(INFINITE);
162  
-        }
163  
-      }
164  
-    };
165  
-
166  
-    /**
167  
-     * This is condition variable implementation that uses the Vista (or later)
168  
-     * windows api but it is safe to compile, link, and load on Xp.
169  
-     */
170  
-    class ConditionVariableVista : public NonCopyable
  38
+    // SleepConditionVarialbeCS requires the condition variable be entered
  39
+    //  only once.
  40
+    struct AlmostExit 
171 41
     {
172  
-      friend class ConditionVariable;
173  
-
174  
-      CONDITION_VARIABLE cond;
175  
-
176  
-      typedef VOID (WINAPI *TakesCV)(PCONDITION_VARIABLE);
177  
-      typedef BOOL (WINAPI *SleepCVCS)(PCONDITION_VARIABLE, PCRITICAL_SECTION, DWORD);
178  
-
179  
-      static bool setConditionVarFuncs();
180  
-      static TakesCV InitializeConditionVariableProc;
181  
-      static SleepCVCS SleepConditionVariableCSProc;
182  
-      static TakesCV WakeConditionVariableProc;
183  
-      static TakesCV WakeAllConditionVariableProc;
184  
-
185  
-      inline ConditionVariableVista() { }
186  
-
187  
-    inline void Init() { (*InitializeConditionVariableProc)(&cond); }
188  
-
189  
-      // apparently, windows condition variables do not need to be deleted
190  
-      inline ~ConditionVariableVista() { }
191  
-
192  
-      inline void wait(CCriticalSection& lock) 
193  
-      { 
194  
-        // even the windows implementation is capable of spontaneous wakes
195  
-        (*SleepConditionVariableCSProc)(&cond,&lock.get_underlying().mutex,INFINITE);
196  
-      }
197  
-
198  
-      inline bool wait(CCriticalSection& lock, unsigned long milliseconds) 
199  
-      { 
200  
-        return (*SleepConditionVariableCSProc)(&cond,&lock.get_underlying().mutex,milliseconds) ? true : false;
201  
-      }
202  
-
203  
-      inline void wait(CSingleLock& lock) { wait(lock.get_underlying()); }
204  
-      inline bool wait(CSingleLock& lock, unsigned long milliseconds) { return wait(lock.get_underlying(), milliseconds); }
205  
-      inline void notifyAll() { (*WakeAllConditionVariableProc)(&cond); }
206  
-      inline void notify() { (*WakeConditionVariableProc)(&cond); }
  42
+      unsigned int count;
  43
+      CCriticalSection& cc;
  44
+      inline AlmostExit(CCriticalSection& pcc) : count(pcc.exit(1)), cc(pcc) { cc.count = 0; }
  45
+      inline ~AlmostExit() { cc.count = 1; cc.restore(count); }
207 46
     };
208  
-  }
209 47
 
210  
-#define XBMC_CV(func) if (isVista) vistaimpl. func ;else xpimpl. func 
211  
-#define XBMC_RCV(func) (isVista ? vistaimpl. func : xpimpl. func )
212  
-  class ConditionVariable : public NonCopyable
213  
-  {
214  
-    // stupid hack for statics
215  
-    static bool isIsVistaSet;
216  
-    static bool isVista;
217  
-    static bool getIsVista();
218  
-    intern::ConditionVariableXp xpimpl;
219  
-    intern::ConditionVariableVista vistaimpl;
220 48
   public:
221  
-    inline ConditionVariable()
222  
-    {
223  
-      if (isIsVistaSet ? isVista : getIsVista())
224  
-        vistaimpl.Init();
225  
-      else
226  
-        xpimpl.Init();
227  
-    }
  49
+    inline ConditionVariable() { InitializeConditionVariable(&cond); }
228 50
 
229  
-    inline void wait(CCriticalSection& lock)
230  
-    {
231  
-      int  count = lock.count;
232  
-      lock.count = 0;
233  
-      XBMC_CV(wait(lock));
234  
-      lock.count = count;
  51
+    // apparently, windows condition variables do not need to be deleted
  52
+    inline ~ConditionVariable() { }
  53
+
  54
+    inline void wait(CCriticalSection& lock) 
  55
+    { 
  56
+      AlmostExit ae(lock);
  57
+      // even the windows implementation is capable of spontaneous wakes
  58
+      SleepConditionVariableCS(&cond,&lock.get_underlying().mutex,INFINITE);
235 59
     }
236 60
 
237  
-    inline bool wait(CCriticalSection& lock, unsigned long milliseconds)
238  
-    {
239  
-      int  count = lock.count;
240  
-      lock.count = 0;
241  
-      bool res   = XBMC_RCV(wait(lock, milliseconds));
242  
-      lock.count = count;
243  
-      return res;
  61
+    inline bool wait(CCriticalSection& lock, unsigned long milliseconds) 
  62
+    { 
  63
+      AlmostExit ae(lock);
  64
+      return SleepConditionVariableCS(&cond,&lock.get_underlying().mutex,milliseconds) ? true : false;
244 65
     }
245 66
 
246 67
     inline void wait(CSingleLock& lock) { wait(lock.get_underlying()); }
247 68
     inline bool wait(CSingleLock& lock, unsigned long milliseconds) { return wait(lock.get_underlying(), milliseconds); }
248  
-
249  
-
250  
-    inline void notifyAll() { XBMC_CV(notifyAll()); }
251  
-    inline void notify() { XBMC_CV(notify()); }
  69
+    inline void notifyAll() { WakeAllConditionVariable(&cond); }
  70
+    inline void notify() { WakeConditionVariable(&cond); }
252 71
   };
253 72
 }
11  xbmc/threads/platform/win/CriticalSection.h
@@ -27,12 +27,8 @@
27 27
 namespace XbmcThreads
28 28
 {
29 29
 
30  
-  namespace intern
31  
-  {
32  
-    // forward declare in preparation for the friend declaration
33  
-    class ConditionVariableVista;
34  
-    class ConditionVariableXp;
35  
-  }
  30
+  // forward declare in preparation for the friend declaration
  31
+  class ConditionVariable;
36 32
 
37 33
   namespace windows
38 34
   {
@@ -41,8 +37,7 @@ namespace XbmcThreads
41 37
       CRITICAL_SECTION mutex;
42 38
 
43 39
       // needs acces to 'mutex'
44  
-      friend class XbmcThreads::intern::ConditionVariableVista;
45  
-      friend class XbmcThreads::intern::ConditionVariableXp;
  40
+      friend class XbmcThreads::ConditionVariable;
46 41
     public:
47 42
       inline RecursiveMutex()
48 43
       {
68  xbmc/threads/platform/win/Implementation.cpp
... ...
@@ -1,68 +0,0 @@
1  
-/*
2  
- *      Copyright (C) 2005-2013 Team XBMC
3  
- *      http://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, see
17  
- *  <http://www.gnu.org/licenses/>.
18  
- *
19  
- */
20  
-
21  
-#include "threads/Condition.h"
22  
-
23  
-namespace XbmcThreads
24  
-{
25  
-
26  
-  namespace intern
27  
-  {
28  
-    ConditionVariableVista::TakesCV ConditionVariableVista::InitializeConditionVariableProc;
29  
-    ConditionVariableVista::SleepCVCS ConditionVariableVista::SleepConditionVariableCSProc;
30  
-    ConditionVariableVista::TakesCV ConditionVariableVista::WakeConditionVariableProc;
31  
-    ConditionVariableVista::TakesCV ConditionVariableVista::WakeAllConditionVariableProc;
32  
-
33  
-    bool ConditionVariableVista::setConditionVarFuncs()
34  
-    {
35  
-      HMODULE mod = GetModuleHandle("Kernel32");
36  
-
37  
-      if (mod == NULL)
38  
-        return false;
39  
-
40  
-      InitializeConditionVariableProc = (TakesCV)GetProcAddress(mod,"InitializeConditionVariable");
41  
-      if (InitializeConditionVariableProc == NULL)
42  
-        return false;
43  
-    
44  
-      SleepConditionVariableCSProc = (SleepCVCS)GetProcAddress(mod,"SleepConditionVariableCS");
45  
-      WakeAllConditionVariableProc = (TakesCV)GetProcAddress(mod,"WakeAllConditionVariable");
46  
-      WakeConditionVariableProc = (TakesCV)GetProcAddress(mod,"WakeConditionVariable");
47  
-
48  
-      return SleepConditionVariableCSProc != NULL && 
49  
-        WakeAllConditionVariableProc != NULL &&
50  
-        WakeConditionVariableProc != NULL;
51  
-    }
52  
-  }
53  
-
54  
-  bool ConditionVariable::getIsVista()
55  
-  {
56  
-    if (!isIsVistaSet)
57  
-    {
58  
-      isVista = intern::ConditionVariableVista::setConditionVarFuncs();
59  
-      isIsVistaSet = true;
60  
-    }
61  
-
62  
-    return isVista;
63  
-  }
64  
-
65  
-  bool ConditionVariable::isVista = getIsVista();
66  
-  // bss segment nulled out by loader.
67  
-  bool ConditionVariable::isIsVistaSet;
68  
-}

5 notes on commit bcf99dc

Skixbmc

Maybe I missed a patch, but according to let this work under x64 Windows should _WIN32_WINNT and NTDDI_VERSION at least set to Vista.

Martijn Kaijser

minimum installer requirements 6f165fd or do you mean something else?

edit:
gracefully shutting down when trying to run on XP should still be added. but for now we already prevent from installing in the first place

Skixbmc

I mean in the project properties, Preprocessor Definitions.

Skixbmc

Thanks!

Please sign in to comment.
Something went wrong with that request. Please try again.