Skip to content

FIX: GilSafeSingleLock is causing UI freeze when it cannot get the GIL back... #1204

Closed
wants to merge 1 commit into from
View
88 xbmc/interfaces/python/xbmcmodule/window.cpp
@@ -41,17 +41,7 @@ using namespace std;
#define ACTIVE_WINDOW g_windowManager.GetActiveWindow()
-/**
- * A CSingleLock that will relinquish the GIL during the time
- * it takes to obtain the CriticalSection
- */
-class GilSafeSingleLock : public CPyThreadState, public CSingleLock
-{
-public:
- GilSafeSingleLock(const CCriticalSection& critSec) : CPyThreadState(true), CSingleLock(critSec) { CPyThreadState::Restore(); }
-};
-
-#ifdef __cplusplus
+#ifdef __cplusplus
extern "C" {
#endif
@@ -62,15 +52,18 @@ namespace PYXBMC
// used by Dialog to to create a new dialogWindow
bool Window_CreateNewWindow(Window* pWindow, bool bAsDialog)
{
- GilSafeSingleLock lock(g_graphicsContext);
-
+ CPyThreadState state;
+
+ CSingleLock lock(g_graphicsContext);
if (pWindow->iWindowId != -1)
{
// user specified window id, use this one if it exists
// It is not possible to capture key presses or button presses
pWindow->pWindow = g_windowManager.GetWindow(pWindow->iWindowId);
if (!pWindow->pWindow)
{
+ lock.Leave();
+ state.Restore();
PyErr_SetString(PyExc_ValueError, "Window id does not exist");
return false;
}
@@ -84,6 +77,8 @@ namespace PYXBMC
// if window 13099 is in use it means python can't create more windows
if (g_windowManager.GetWindow(WINDOW_PYTHON_END))
{
+ lock.Leave();
+ state.Restore();
PyErr_SetString(PyExc_Exception, "maximum number of windows reached");
return false;
}
@@ -111,6 +106,9 @@ namespace PYXBMC
g_windowManager.Add(pWindow->pWindow);
}
+ lock.Leave();
+ state.Restore();
+
pWindow->iOldWindowId = 0;
pWindow->bModal = false;
pWindow->iCurrentControlId = 3000;
@@ -139,13 +137,16 @@ namespace PYXBMC
}
// lock xbmc GUI before accessing data from it
- GilSafeSingleLock lock(g_graphicsContext);
+ CPyThreadState state;
+ CSingleLock lock(g_graphicsContext);
// check if control exists
CGUIControl* pGUIControl = (CGUIControl*)self->pWindow->GetControl(iControlId);
if (!pGUIControl)
{
// control does not exist.
+ lock.Leave();
+ state.Restore();
CStdString error;
error.Format("Non-Existent Control %d",iControlId);
PyErr_SetString(PyExc_TypeError, error.c_str());
@@ -282,6 +283,9 @@ namespace PYXBMC
break;
}
+ lock.Leave();
+ state.Restore();
+
if (!pControl)
{
// throw an exeption
@@ -342,7 +346,9 @@ namespace PYXBMC
void Window_Dealloc(Window* self)
{
- GilSafeSingleLock lock(g_graphicsContext);
+ CPyThreadState state;
+
+ CSingleLock lock(g_graphicsContext);
if (self->bIsPythonWindow)
{
// first change to an existing window
@@ -399,6 +405,8 @@ namespace PYXBMC
}
lock.Leave();
+ state.Restore();
+
self->vecControls.clear();
self->vecControls.~vector();
self->sFallBackPath.~string();
@@ -632,9 +640,13 @@ namespace PYXBMC
pControl->iParentId = self->iWindowId;
{ // assign control id, if id is already in use, try next id
- GilSafeSingleLock lock(g_graphicsContext);
+ CPyThreadState state;
+
+ CSingleLock lock(g_graphicsContext);
do pControl->iControlId = ++self->iCurrentControlId;
while (self->pWindow->GetControl(pControl->iControlId));
+ lock.Leave();
+ state.Restore();
}
// Control Label
@@ -830,15 +842,18 @@ namespace PYXBMC
PyObject* Window_GetFocus(Window *self, PyObject *args)
{
- GilSafeSingleLock lock(g_graphicsContext);
-
+ CPyThreadState state;
+
+ CSingleLock lock(g_graphicsContext);
int iControlId = self->pWindow->GetFocusedControlID();
+ lock.Leave();
+
+ state.Restore();
if(iControlId == -1)
{
PyErr_SetString(PyExc_RuntimeError, "No control in this window has focus");
return NULL;
}
- lock.Leave();
return (PyObject*)Window_GetControlById(self, iControlId);
}
@@ -851,8 +866,13 @@ namespace PYXBMC
PyObject* Window_GetFocusId(Window *self, PyObject *args)
{
- GilSafeSingleLock lock(g_graphicsContext);
+ CPyThreadState state;
+
+ CSingleLock lock(g_graphicsContext);
int iControlId = self->pWindow->GetFocusedControlID();
+ lock.Leave();
+
+ state.Restore();
if(iControlId == -1)
{
PyErr_SetString(PyExc_RuntimeError, "No control in this window has focus");
@@ -972,8 +992,13 @@ namespace PYXBMC
return NULL;
}
- GilSafeSingleLock lock(g_graphicsContext);
+ CPyThreadState state;
+
+ CSingleLock lock(g_graphicsContext);
self->pWindow->SetCoordsRes(g_settings.m_ResInfo[res]);
+ lock.Leave();
+
+ state.Restore();
Py_INCREF(Py_None);
return Py_None;
@@ -1056,9 +1081,14 @@ namespace PYXBMC
return NULL; }
if (!key) return NULL;
- GilSafeSingleLock lock(g_graphicsContext);
+ CPyThreadState state;
+
+ CSingleLock lock(g_graphicsContext);
CStdString lowerKey = key;
string value = self->pWindow->GetProperty(lowerKey.ToLower()).asString();
+ lock.Leave();
+
+ state.Restore();
return Py_BuildValue((char*)"s", value.c_str());
}
@@ -1091,10 +1121,15 @@ namespace PYXBMC
return NULL;
}
if (!key) return NULL;
- GilSafeSingleLock lock(g_graphicsContext);
+ CPyThreadState state;
+
+ CSingleLock lock(g_graphicsContext);
CStdString lowerKey = key;
self->pWindow->SetProperty(lowerKey.ToLower(), "");
+ lock.Leave();
+
+ state.Restore();
Py_INCREF(Py_None);
return Py_None;
@@ -1109,8 +1144,13 @@ namespace PYXBMC
PyObject* Window_ClearProperties(Window *self, PyObject *args)
{
- GilSafeSingleLock lock(g_graphicsContext);
+ CPyThreadState state;
+
+ CSingleLock lock(g_graphicsContext);
self->pWindow->ClearProperties();
+ lock.Leave();
+
+ state.Restore();
Py_INCREF(Py_None);
return Py_None;
Something went wrong with that request. Please try again.