From 1ad325a680e8ee4dc174c51b7093ada16e014d23 Mon Sep 17 00:00:00 2001 From: "Chris \"Koying\" Browet" Date: Mon, 23 Jul 2012 00:46:26 +0200 Subject: [PATCH] FIX: GilSafeSingleLock is causing UI freeze when it cannot get the GIL back while having already locked the graphic context. Removing it. --- xbmc/interfaces/python/xbmcmodule/window.cpp | 88 ++++++++++++++------ 1 file changed, 64 insertions(+), 24 deletions(-) diff --git a/xbmc/interfaces/python/xbmcmodule/window.cpp b/xbmc/interfaces/python/xbmcmodule/window.cpp index 6576c7ccf9173..f52d0ae44ce19 100644 --- a/xbmc/interfaces/python/xbmcmodule/window.cpp +++ b/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,8 +52,9 @@ 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 @@ -71,6 +62,8 @@ namespace PYXBMC 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;