Skip to content
This repository
Browse code

Merge pull request #2191 from jimfcarroll/fix-14048

Fix #14048 - Change the locking in XBPython/XBPyThread
  • Loading branch information...
commit 94c518f2fdeb1813d0e53dfb95f98fd999ecd60e 2 parents c2a21de + 6f87d6b
authored February 08, 2013
18  xbmc/interfaces/python/XBPyThread.cpp
@@ -261,7 +261,7 @@ void XBPyThread::Process()
261 261
 
262 262
   // we need to check if we was asked to abort before we had inited
263 263
   bool stopping = false;
264  
-  { CSingleLock lock(m_pExecuter->m_critSection);
  264
+  { CSingleLock lock(m_critSec);
265 265
     m_threadState = state;
266 266
     stopping = m_stopping;
267 267
   }
@@ -389,13 +389,13 @@ void XBPyThread::Process()
389 389
   PyEval_ReleaseLock();
390 390
 
391 391
   //set stopped event - this allows ::stop to run and kill remaining threads
392  
-  //this event has to be fired without holding m_pExecuter->m_critSection
393  
-  //before
  392
+  //this event has to be fired without holding m_critSec
  393
+  //
394 394
   //Also the GIL (PyEval_AcquireLock) must not be held
395 395
   //if not obeyed there is still no deadlock because ::stop waits with timeout (smart one!)
396 396
   stoppedEvent.Set();
397 397
 
398  
-  { CSingleLock lock(m_pExecuter->m_critSection);
  398
+  { CSingleLock lock(m_critSec);
399 399
     m_threadState = NULL;
400 400
   }
401 401
 
@@ -440,7 +440,7 @@ void XBPyThread::OnException()
440 440
   PyThreadState_Swap(NULL);
441 441
   PyEval_ReleaseLock();
442 442
 
443  
-  CSingleLock lock(m_pExecuter->m_critSection);
  443
+  CSingleLock lock(m_critSec);
444 444
   m_threadState = NULL;
445 445
   CLog::Log(LOGERROR,"%s, abnormally terminating python thread", __FUNCTION__);
446 446
   m_pExecuter->setDone(m_id);
@@ -452,7 +452,7 @@ bool XBPyThread::isStopping() {
452 452
 
453 453
 void XBPyThread::stop()
454 454
 {
455  
-  CSingleLock lock(m_pExecuter->m_critSection);
  455
+  CSingleLock lock(m_critSec);
456 456
   if(m_stopping)
457 457
     return;
458 458
 
@@ -499,12 +499,12 @@ void XBPyThread::stop()
499 499
     
500 500
     //everything which didn't exit by now gets killed
501 501
     {
502  
-      // grabbing the PyLock while holding the XBPython m_critSection is asking for a deadlock
503  
-      CSingleExit ex2(m_pExecuter->m_critSection);
  502
+      // grabbing the PyLock while holding the m_critSec is asking for a deadlock
  503
+      CSingleExit ex2(m_critSec);
504 504
       PyEval_AcquireLock();
505 505
     }
506 506
 
507  
-    // since we released the XBPython m_critSection it's possible that the state is cleaned up 
  507
+    // Since we released the m_critSec it's possible that the state is cleaned up 
508 508
     // so we need to recheck for m_threadState == NULL
509 509
     if (m_threadState)
510 510
     {
2  xbmc/interfaces/python/XBPyThread.h
@@ -24,6 +24,7 @@
24 24
 
25 25
 #include "threads/Thread.h"
26 26
 #include "threads/Event.h"
  27
+#include "threads/CriticalSection.h"
27 28
 #include "addons/IAddon.h"
28 29
 
29 30
 class XBPython;
@@ -42,6 +43,7 @@ class XBPyThread : public CThread
42 43
   void setAddon(ADDON::AddonPtr _addon) { addon = _addon; }
43 44
 
44 45
 protected:
  46
+  CCriticalSection m_critSec;
45 47
   XBPython *m_pExecuter;
46 48
   CEvent stoppedEvent;
47 49
   void *m_threadState;
271  xbmc/interfaces/python/XBPython.cpp
@@ -26,6 +26,8 @@
26 26
 // python.h should always be included first before any other includes
27 27
 #include <Python.h>
28 28
 
  29
+#include <algorithm>
  30
+
29 31
 #include "system.h"
30 32
 #include "cores/DllLoader/DllLoaderContainer.h"
31 33
 #include "GUIPassword.h"
@@ -79,20 +81,24 @@ XBPython::~XBPython()
79 81
   CAnnouncementManager::RemoveAnnouncer(this);
80 82
 }
81 83
 
  84
+#define LOCK_AND_COPY(type, dest, src) \
  85
+  if (!m_bInitialized) return; \
  86
+  CSingleLock lock(src); \
  87
+  src.hadSomethingRemoved = false; \
  88
+  type dest; \
  89
+  dest = src
  90
+
  91
+#define CHECK_FOR_ENTRY(l,v) \
  92
+  (l.hadSomethingRemoved ? (std::find(l.begin(),l.end(),v) != l.end()) : true)
  93
+
82 94
 // message all registered callbacks that xbmc stopped playing
83 95
 void XBPython::OnPlayBackEnded()
84 96
 {
85 97
   TRACE;
86  
-  CSingleLock lock(m_critSection);
87  
-  if (m_bInitialized)
88  
-  {
89  
-    PlayerCallbackList::iterator it = m_vecPlayerCallbackList.begin();
90  
-    while (it != m_vecPlayerCallbackList.end())
91  
-    {
  98
+  LOCK_AND_COPY(std::vector<PVOID>,tmp,m_vecPlayerCallbackList);
  99
+  for (PlayerCallbackList::iterator it = tmp.begin(); (it != tmp.end()); it++)
  100
+    if (CHECK_FOR_ENTRY(m_vecPlayerCallbackList,(*it)))
92 101
       ((IPlayerCallback*)(*it))->OnPlayBackEnded();
93  
-      it++;
94  
-    }
95  
-  }
96 102
 }
97 103
 
98 104
 void XBPython::Announce(AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data)
@@ -124,145 +130,101 @@ void XBPython::Announce(AnnouncementFlag flag, const char *sender, const char *m
124 130
 void XBPython::OnPlayBackStarted()
125 131
 {
126 132
   TRACE;
127  
-  CSingleLock lock(m_critSection);
128  
-  if (m_bInitialized)
129  
-  {
130  
-    PlayerCallbackList::iterator it = m_vecPlayerCallbackList.begin();
131  
-    while (it != m_vecPlayerCallbackList.end())
132  
-    {
  133
+  LOCK_AND_COPY(std::vector<PVOID>,tmp,m_vecPlayerCallbackList);
  134
+  for (PlayerCallbackList::iterator it = tmp.begin(); (it != tmp.end()); it++)
  135
+    if (CHECK_FOR_ENTRY(m_vecPlayerCallbackList,(*it)))
133 136
       ((IPlayerCallback*)(*it))->OnPlayBackStarted();
134  
-      it++;
135  
-    }
136  
-  }
137 137
 }
138 138
 
139 139
 // message all registered callbacks that we paused playing
140 140
 void XBPython::OnPlayBackPaused()
141 141
 {
142  
-  CSingleLock lock(m_critSection);
143  
-  if (m_bInitialized)
144  
-  {
145  
-    PlayerCallbackList::iterator it = m_vecPlayerCallbackList.begin();
146  
-    while (it != m_vecPlayerCallbackList.end())
147  
-    {
  142
+  TRACE;
  143
+  LOCK_AND_COPY(std::vector<PVOID>,tmp,m_vecPlayerCallbackList);
  144
+  for (PlayerCallbackList::iterator it = tmp.begin(); (it != tmp.end()); it++)
  145
+    if (CHECK_FOR_ENTRY(m_vecPlayerCallbackList,(*it)))
148 146
       ((IPlayerCallback*)(*it))->OnPlayBackPaused();
149  
-      it++;
150  
-    }
151  
-  }
152 147
 }
153 148
 
154 149
 // message all registered callbacks that we resumed playing
155 150
 void XBPython::OnPlayBackResumed()
156 151
 {
157 152
   TRACE;
158  
-  CSingleLock lock(m_critSection);
159  
-  if (m_bInitialized)
160  
-  {
161  
-    PlayerCallbackList::iterator it = m_vecPlayerCallbackList.begin();
162  
-    while (it != m_vecPlayerCallbackList.end())
163  
-    {
  153
+  LOCK_AND_COPY(std::vector<PVOID>,tmp,m_vecPlayerCallbackList);
  154
+  for (PlayerCallbackList::iterator it = tmp.begin(); (it != tmp.end()); it++)
  155
+    if (CHECK_FOR_ENTRY(m_vecPlayerCallbackList,(*it)))
164 156
       ((IPlayerCallback*)(*it))->OnPlayBackResumed();
165  
-      it++;
166  
-    }
167  
-  }
168 157
 }
169 158
 
170 159
 // message all registered callbacks that user stopped playing
171 160
 void XBPython::OnPlayBackStopped()
172 161
 {
173 162
   TRACE;
174  
-  CSingleLock lock(m_critSection);
175  
-  if (m_bInitialized)
176  
-  {
177  
-    PlayerCallbackList::iterator it = m_vecPlayerCallbackList.begin();
178  
-    while (it != m_vecPlayerCallbackList.end())
179  
-    {
  163
+  LOCK_AND_COPY(std::vector<PVOID>,tmp,m_vecPlayerCallbackList);
  164
+  for (PlayerCallbackList::iterator it = tmp.begin(); (it != tmp.end()); it++)
  165
+    if (CHECK_FOR_ENTRY(m_vecPlayerCallbackList,(*it)))
180 166
       ((IPlayerCallback*)(*it))->OnPlayBackStopped();
181  
-      it++;
182  
-    }
183  
-  }
184 167
 }
185 168
 
186 169
 // message all registered callbacks that playback speed changed (FF/RW)
187 170
 void XBPython::OnPlayBackSpeedChanged(int iSpeed)
188 171
 {
189 172
   TRACE;
190  
-  CSingleLock lock(m_critSection);
191  
-  if (m_bInitialized)
192  
-  {
193  
-    PlayerCallbackList::iterator it = m_vecPlayerCallbackList.begin();
194  
-    while (it != m_vecPlayerCallbackList.end())
195  
-    {
  173
+  LOCK_AND_COPY(std::vector<PVOID>,tmp,m_vecPlayerCallbackList);
  174
+  for (PlayerCallbackList::iterator it = tmp.begin(); (it != tmp.end()); it++)
  175
+    if (CHECK_FOR_ENTRY(m_vecPlayerCallbackList,(*it)))
196 176
       ((IPlayerCallback*)(*it))->OnPlayBackSpeedChanged(iSpeed);
197  
-      it++;
198  
-    }
199  
-  }
200 177
 }
201 178
 
202 179
 // message all registered callbacks that player is seeking
203 180
 void XBPython::OnPlayBackSeek(int iTime, int seekOffset)
204 181
 {
205 182
   TRACE;
206  
-  CSingleLock lock(m_critSection);
207  
-  if (m_bInitialized)
208  
-  {
209  
-    PlayerCallbackList::iterator it = m_vecPlayerCallbackList.begin();
210  
-    while (it != m_vecPlayerCallbackList.end())
211  
-    {
  183
+  LOCK_AND_COPY(std::vector<PVOID>,tmp,m_vecPlayerCallbackList);
  184
+  for (PlayerCallbackList::iterator it = tmp.begin(); (it != tmp.end()); it++)
  185
+    if (CHECK_FOR_ENTRY(m_vecPlayerCallbackList,(*it)))
212 186
       ((IPlayerCallback*)(*it))->OnPlayBackSeek(iTime, seekOffset);
213  
-      it++;
214  
-    }
215  
-  }
216 187
 }
217 188
 
218 189
 // message all registered callbacks that player chapter seeked
219 190
 void XBPython::OnPlayBackSeekChapter(int iChapter)
220 191
 {
221 192
   TRACE;
222  
-  CSingleLock lock(m_critSection);
223  
-  if (m_bInitialized)
224  
-  {
225  
-    PlayerCallbackList::iterator it = m_vecPlayerCallbackList.begin();
226  
-    while (it != m_vecPlayerCallbackList.end())
227  
-    {
  193
+  LOCK_AND_COPY(std::vector<PVOID>,tmp,m_vecPlayerCallbackList);
  194
+  for (PlayerCallbackList::iterator it = tmp.begin(); (it != tmp.end()); it++)
  195
+    if (CHECK_FOR_ENTRY(m_vecPlayerCallbackList,(*it)))
228 196
       ((IPlayerCallback*)(*it))->OnPlayBackSeekChapter(iChapter);
229  
-      it++;
230  
-    }
231  
-  }
232 197
 }
233 198
 
234 199
 // message all registered callbacks that next item has been queued
235 200
 void XBPython::OnQueueNextItem()
236 201
 {
237 202
   TRACE;
238  
-  CSingleLock lock(m_critSection);
239  
-  if (m_bInitialized)
240  
-  {
241  
-    PlayerCallbackList::iterator it = m_vecPlayerCallbackList.begin();
242  
-    while (it != m_vecPlayerCallbackList.end())
243  
-    {
  203
+  LOCK_AND_COPY(std::vector<PVOID>,tmp,m_vecPlayerCallbackList);
  204
+  for (PlayerCallbackList::iterator it = tmp.begin(); (it != tmp.end()); it++)
  205
+    if (CHECK_FOR_ENTRY(m_vecPlayerCallbackList,(*it)))
244 206
       ((IPlayerCallback*)(*it))->OnQueueNextItem();
245  
-      it++;
246  
-    }
247  
-  }
248 207
 }
249 208
 
250 209
 void XBPython::RegisterPythonPlayerCallBack(IPlayerCallback* pCallback)
251 210
 {
252 211
   TRACE;
253  
-  CSingleLock lock(m_critSection);
  212
+  CSingleLock lock(m_vecPlayerCallbackList);
254 213
   m_vecPlayerCallbackList.push_back(pCallback);
255 214
 }
256 215
 
257 216
 void XBPython::UnregisterPythonPlayerCallBack(IPlayerCallback* pCallback)
258 217
 {
259 218
   TRACE;
260  
-  CSingleLock lock(m_critSection);
  219
+  CSingleLock lock(m_vecPlayerCallbackList);
261 220
   PlayerCallbackList::iterator it = m_vecPlayerCallbackList.begin();
262 221
   while (it != m_vecPlayerCallbackList.end())
263 222
   {
264 223
     if (*it == pCallback)
  224
+    {
265 225
       it = m_vecPlayerCallbackList.erase(it);
  226
+      m_vecPlayerCallbackList.hadSomethingRemoved = true;
  227
+    }
266 228
     else
267 229
       it++;
268 230
   }
@@ -271,19 +233,22 @@ void XBPython::UnregisterPythonPlayerCallBack(IPlayerCallback* pCallback)
271 233
 void XBPython::RegisterPythonMonitorCallBack(XBMCAddon::xbmc::Monitor* pCallback)
272 234
 {
273 235
   TRACE;
274  
-  CSingleLock lock(m_critSection);
  236
+  CSingleLock lock(m_vecMonitorCallbackList);
275 237
   m_vecMonitorCallbackList.push_back(pCallback);
276 238
 }
277 239
 
278 240
 void XBPython::UnregisterPythonMonitorCallBack(XBMCAddon::xbmc::Monitor* pCallback)
279 241
 {
280 242
   TRACE;
281  
-  CSingleLock lock(m_critSection);
  243
+  CSingleLock lock(m_vecMonitorCallbackList);
282 244
   MonitorCallbackList::iterator it = m_vecMonitorCallbackList.begin();
283 245
   while (it != m_vecMonitorCallbackList.end())
284 246
   {
285 247
     if (*it == pCallback)
  248
+    {
286 249
       it = m_vecMonitorCallbackList.erase(it);
  250
+      m_vecMonitorCallbackList.hadSomethingRemoved = true;
  251
+    }
287 252
     else
288 253
       it++;
289 254
   }
@@ -292,98 +257,60 @@ void XBPython::UnregisterPythonMonitorCallBack(XBMCAddon::xbmc::Monitor* pCallba
292 257
 void XBPython::OnSettingsChanged(const CStdString &ID)
293 258
 {
294 259
   TRACE;
295  
-  CSingleLock lock(m_critSection);
296  
-  if (m_bInitialized)
297  
-  {
298  
-    MonitorCallbackList::iterator it = m_vecMonitorCallbackList.begin();
299  
-    while (it != m_vecMonitorCallbackList.end())
300  
-    { 
301  
-      if (((XBMCAddon::xbmc::Monitor*)(*it))->GetId() == ID)  
302  
-        ((XBMCAddon::xbmc::Monitor*)(*it))->OnSettingsChanged();
303  
-      it++;
304  
-    }
305  
-  }  
  260
+  LOCK_AND_COPY(std::vector<XBMCAddon::xbmc::Monitor*>,tmp,m_vecMonitorCallbackList);
  261
+  for (MonitorCallbackList::iterator it = tmp.begin(); (it != tmp.end()); it++)
  262
+    if (CHECK_FOR_ENTRY(m_vecMonitorCallbackList,(*it)) && ((*it)->GetId() == ID))
  263
+      (*it)->OnSettingsChanged();
306 264
 }  
307 265
 
308 266
 void XBPython::OnScreensaverActivated()
309 267
 {
310 268
   TRACE;
311  
-  CSingleLock lock(m_critSection);
312  
-  if (m_bInitialized)
313  
-  {
314  
-    MonitorCallbackList::iterator it = m_vecMonitorCallbackList.begin();
315  
-    while (it != m_vecMonitorCallbackList.end())
316  
-    {
317  
-      ((XBMCAddon::xbmc::Monitor*)(*it))->OnScreensaverActivated();
318  
-      it++;
319  
-    }
320  
-  }  
  269
+  LOCK_AND_COPY(std::vector<XBMCAddon::xbmc::Monitor*>,tmp,m_vecMonitorCallbackList);
  270
+  for (MonitorCallbackList::iterator it = tmp.begin(); (it != tmp.end()); it++)
  271
+    if (CHECK_FOR_ENTRY(m_vecMonitorCallbackList,(*it)))
  272
+      (*it)->OnScreensaverActivated();
321 273
 } 
322 274
 
323 275
 void XBPython::OnScreensaverDeactivated()
324 276
 {
325 277
   TRACE;
326  
-  CSingleLock lock(m_critSection);
327  
-  if (m_bInitialized)
328  
-  {
329  
-    MonitorCallbackList::iterator it = m_vecMonitorCallbackList.begin();
330  
-    while (it != m_vecMonitorCallbackList.end())
331  
-    {
332  
-      ((XBMCAddon::xbmc::Monitor*)(*it))->OnScreensaverDeactivated();
333  
-      it++;
334  
-    }
335  
-  }  
  278
+  LOCK_AND_COPY(std::vector<XBMCAddon::xbmc::Monitor*>,tmp,m_vecMonitorCallbackList);
  279
+  for (MonitorCallbackList::iterator it = tmp.begin(); (it != tmp.end()); it++)
  280
+    if (CHECK_FOR_ENTRY(m_vecMonitorCallbackList,(*it)))
  281
+      (*it)->OnScreensaverDeactivated();
336 282
 } 
337 283
 
338 284
 void XBPython::OnDatabaseUpdated(const std::string &database)
339 285
 {
340 286
   TRACE;
341  
- CSingleLock lock(m_critSection);
342  
- if (m_bInitialized)
343  
- {
344  
-  MonitorCallbackList::iterator it = m_vecMonitorCallbackList.begin();
345  
-  while (it != m_vecMonitorCallbackList.end())
346  
-  {
347  
-   ((XBMCAddon::xbmc::Monitor*)(*it))->OnDatabaseUpdated(database);
348  
-   it++;
349  
-  }
350  
- }  
  287
+  LOCK_AND_COPY(std::vector<XBMCAddon::xbmc::Monitor*>,tmp,m_vecMonitorCallbackList);
  288
+  for (MonitorCallbackList::iterator it = tmp.begin(); (it != tmp.end()); it++)
  289
+    if (CHECK_FOR_ENTRY(m_vecMonitorCallbackList,(*it)))
  290
+      (*it)->OnDatabaseUpdated(database);
351 291
 } 
352 292
 
353 293
 void XBPython::OnDatabaseScanStarted(const std::string &database)
354 294
 {
355 295
   TRACE;
356  
-  CSingleLock lock(m_critSection);
357  
-  if (m_bInitialized)
358  
-  {
359  
-    MonitorCallbackList::iterator it = m_vecMonitorCallbackList.begin();
360  
-    while (it != m_vecMonitorCallbackList.end())
361  
-    {
362  
-      ((XBMCAddon::xbmc::Monitor*)(*it))->OnDatabaseScanStarted(database);
363  
-      it++;
364  
-    }
365  
-  }  
  296
+  LOCK_AND_COPY(std::vector<XBMCAddon::xbmc::Monitor*>,tmp,m_vecMonitorCallbackList);
  297
+  for (MonitorCallbackList::iterator it = tmp.begin(); (it != tmp.end()); it++)
  298
+    if (CHECK_FOR_ENTRY(m_vecMonitorCallbackList,(*it)))
  299
+      (*it)->OnDatabaseScanStarted(database);
366 300
 }
367 301
 
368 302
 void XBPython::OnAbortRequested(const CStdString &ID)
369 303
 {
370 304
   TRACE;
371  
-  CSingleLock lock(m_critSection);
372  
-  if (m_bInitialized)
  305
+  LOCK_AND_COPY(std::vector<XBMCAddon::xbmc::Monitor*>,tmp,m_vecMonitorCallbackList);
  306
+  for (MonitorCallbackList::iterator it = tmp.begin(); (it != tmp.end()); it++)
373 307
   {
374  
-    MonitorCallbackList::iterator it = m_vecMonitorCallbackList.begin();
375  
-    while (it != m_vecMonitorCallbackList.end())
  308
+    if (CHECK_FOR_ENTRY(m_vecMonitorCallbackList,(*it)))
376 309
     {
377 310
       if (ID.IsEmpty())
378  
-      {    
379  
-        ((XBMCAddon::xbmc::Monitor*)(*it))->OnAbortRequested();
380  
-      }
381  
-      else
382  
-      {
383  
-        if (((XBMCAddon::xbmc::Monitor*)(*it))->GetId() == ID)
384  
-          ((XBMCAddon::xbmc::Monitor*)(*it))->OnAbortRequested();
385  
-      }
386  
-      it++;
  311
+        (*it)->OnAbortRequested();
  312
+      else if ((*it)->GetId() == ID)
  313
+        (*it)->OnAbortRequested();
387 314
     }
388 315
   }  
389 316
 } 
@@ -633,6 +560,8 @@ void XBPython::FinalizeScript()
633 560
   m_endtime = XbmcThreads::SystemClockMillis();
634 561
 }
635 562
 
  563
+
  564
+// Always called with the lock held on m_critSection
636 565
 void XBPython::Finalize()
637 566
 {
638 567
   TRACE;
@@ -673,19 +602,14 @@ void XBPython::Finalize()
673 602
 
674 603
 void XBPython::FreeResources()
675 604
 {
676  
-  CSingleLock lock(m_critSection);
677  
-  if (m_bInitialized)
678  
-  {
679  
-    // with the m_critSection held, we should copy the PyList so that 
680  
-    // we can operate on the values once we release it.
681  
-    PyList tmpvec = m_vecPyList;
682  
-    m_vecPyList.clear();
  605
+  LOCK_AND_COPY(std::vector<PyElem>,tmpvec,m_vecPyList);
  606
+  m_vecPyList.clear();
  607
+  m_vecPyList.hadSomethingRemoved = true;
683 608
 
684  
-    lock.Leave(); //unlock here because the python thread might lock when it exits
  609
+  lock.Leave(); //unlock here because the python thread might lock when it exits
685 610
 
686  
-    // cleanup threads that are still running
687  
-    tmpvec.clear(); // boost releases the XBPyThreads which, if deleted, calls FinalizeScript
688  
-  }
  611
+  // cleanup threads that are still running
  612
+  tmpvec.clear(); // boost releases the XBPyThreads which, if deleted, calls FinalizeScript
689 613
 }
690 614
 
691 615
 void XBPython::Process()
@@ -703,7 +627,7 @@ void XBPython::Process()
703 627
       CLog::Log(LOGDEBUG, "%s - no profile autoexec.py (%s) found, skipping", __FUNCTION__, strAutoExecPy.c_str());
704 628
   }
705 629
 
706  
-  CSingleLock lock(m_critSection);
  630
+  CSingleLock lock(m_vecPyList);
707 631
 
708 632
   if (m_bInitialized)
709 633
   {
@@ -714,6 +638,7 @@ void XBPython::Process()
714 638
       {
715 639
         tmpvec.push_back(*it);
716 640
         it = m_vecPyList.erase(it);
  641
+        m_vecPyList.hadSomethingRemoved = true;
717 642
       }
718 643
       else
719 644
         it++;
@@ -723,8 +648,11 @@ void XBPython::Process()
723 648
     //delete scripts which are done
724 649
     tmpvec.clear(); // boost releases the XBPyThreads which, if deleted, calls FinalizeScript
725 650
 
  651
+    CSingleLock l2(m_critSection);
726 652
     if(m_iDllScriptCounter == 0 && (XbmcThreads::SystemClockMillis() - m_endtime) > 10000 )
  653
+    {
727 654
       Finalize();
  655
+    }
728 656
   }
729 657
 }
730 658
 
@@ -766,7 +694,7 @@ int XBPython::evalFile(const CStdString &src, const std::vector<CStdString> &arg
766 694
   if (g_settings.GetCurrentProfile().programsLocked() && !g_passwordManager.IsMasterLockUnlocked(true))
767 695
     return -1;
768 696
 
769  
-  CSingleLock lock(m_critSection);
  697
+  CSingleLock lock(m_vecPyList);
770 698
   Initialize();
771 699
 
772 700
   if (!m_bInitialized) return -1;
@@ -789,7 +717,7 @@ int XBPython::evalFile(const CStdString &src, const std::vector<CStdString> &arg
789 717
 
790 718
 void XBPython::setDone(int id)
791 719
 {
792  
-  CSingleLock lock(m_critSection);
  720
+  CSingleLock lock(m_vecPyList);
793 721
   PyList::iterator it = m_vecPyList.begin();
794 722
   while (it != m_vecPyList.end())
795 723
   {
@@ -808,7 +736,7 @@ void XBPython::setDone(int id)
808 736
 void XBPython::stopScript(int id)
809 737
 {
810 738
   CSingleExit ex(g_graphicsContext);
811  
-  CSingleLock lock(m_critSection);
  739
+  CSingleLock lock(m_vecPyList);
812 740
   PyList::iterator it = m_vecPyList.begin();
813 741
   while (it != m_vecPyList.end())
814 742
   {
@@ -829,7 +757,7 @@ void* XBPython::getMainThreadState()
829 757
 
830 758
 int XBPython::ScriptsSize()
831 759
 {
832  
-  CSingleLock lock(m_critSection);
  760
+  CSingleLock lock(m_vecPyList);
833 761
   return m_vecPyList.size();
834 762
 }
835 763
 
@@ -837,7 +765,7 @@ const char* XBPython::getFileName(int scriptId)
837 765
 {
838 766
   const char* cFileName = NULL;
839 767
 
840  
-  CSingleLock lock(m_critSection);
  768
+  CSingleLock lock(m_vecPyList);
841 769
   PyList::iterator it = m_vecPyList.begin();
842 770
   while (it != m_vecPyList.end())
843 771
   {
@@ -853,7 +781,7 @@ int XBPython::getScriptId(const CStdString &strFile)
853 781
 {
854 782
   int iId = -1;
855 783
 
856  
-  CSingleLock lock(m_critSection);
  784
+  CSingleLock lock(m_vecPyList);
857 785
 
858 786
   PyList::iterator it = m_vecPyList.begin();
859 787
   while (it != m_vecPyList.end())
@@ -868,7 +796,7 @@ int XBPython::getScriptId(const CStdString &strFile)
868 796
 
869 797
 bool XBPython::isRunning(int scriptId)
870 798
 {
871  
-  CSingleLock lock(m_critSection);
  799
+  CSingleLock lock(m_vecPyList);
872 800
 
873 801
   for(PyList::iterator it = m_vecPyList.begin(); it != m_vecPyList.end(); it++)
874 802
   {
@@ -887,7 +815,7 @@ bool XBPython::isStopping(int scriptId)
887 815
 {
888 816
   bool bStopping = false;
889 817
 
890  
-  CSingleLock lock(m_critSection);
  818
+  CSingleLock lock(m_vecPyList);
891 819
   PyList::iterator it = m_vecPyList.begin();
892 820
   while (it != m_vecPyList.end())
893 821
   {
@@ -901,7 +829,7 @@ bool XBPython::isStopping(int scriptId)
901 829
 
902 830
 int XBPython::GetPythonScriptId(int scriptPosition)
903 831
 {
904  
-  CSingleLock lock(m_critSection);
  832
+  CSingleLock lock(m_vecPyList);
905 833
   return (int)m_vecPyList[scriptPosition].id;
906 834
 }
907 835
 
@@ -946,6 +874,9 @@ int XBPython::evalString(const CStdString &src, const std::vector<CStdString> &a
946 874
   inf.strFile   = "<string>";
947 875
   inf.pyThread  = pyThread;
948 876
 
  877
+  lock.Leave();
  878
+  CSingleLock l2(m_vecPyList);
  879
+
949 880
   m_vecPyList.push_back(inf);
950 881
 
951 882
   return m_nextid;
11  xbmc/interfaces/python/XBPython.h
@@ -47,9 +47,12 @@ namespace XBMCAddon
47 47
   }
48 48
 }
49 49
 
50  
-typedef std::vector<PyElem> PyList;
51  
-typedef std::vector<PVOID> PlayerCallbackList;
52  
-typedef std::vector<XBMCAddon::xbmc::Monitor*> MonitorCallbackList;
  50
+template <class T> struct LockableType : public T, public CCriticalSection 
  51
+{ bool hadSomethingRemoved; };
  52
+
  53
+typedef LockableType<std::vector<PVOID> > PlayerCallbackList;
  54
+typedef LockableType<std::vector<XBMCAddon::xbmc::Monitor*> > MonitorCallbackList;
  55
+typedef LockableType<std::vector<PyElem> > PyList;
53 56
 typedef std::vector<LibraryLoader*> PythonExtensionLibraries;
54 57
 
55 58
 class XBPython : 
@@ -128,8 +131,8 @@ class XBPython :
128 131
   void* getMainThreadState();
129 132
 
130 133
   bool m_bLogin;
131  
-  CCriticalSection    m_critSection;
132 134
 private:
  135
+  CCriticalSection    m_critSection;
133 136
   bool              FileExist(const char* strFile);
134 137
 
135 138
   int               m_nextid;

0 notes on commit 94c518f

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