Commits

Anonymous committed ec3b9a6

Fixed thread dead locks in sdl.time

Comments (0)

Files changed (3)

 * Fix eval(repr(xyz)) for most types.
 * >8 bpp surfaces with palettes - it is supported (although it might be
   pointless) by SDL and so should we.
-* Fix possible dead locks on long running timer callbacks in sdl.time module.
-
 
 * freetype: render to buffer buffer support (like new bytearray, but
   write to a buffer instead)

doc/capi/base.rst

   Returns 1 on succes and 0 on failure.
 
   This will swap the Python interpreter thread state to gain access to
-  the underlying Python stream object. It **should** not be called from
+  the underlying Python stream object. It **should not** be called from
   within the same interpreter thread, as it locks the interpreter stat
   (and thus itself).
 
   of written elements will be stored in *written*.
 
   This will swap the Python interpreter thread state to gain access to
-  the underlying Python stream object. It **should** not be called from
+  the underlying Python stream object. It **should not** be called from
   within the same interpreter thread, as it locks the interpreter stat
   (and thus itself).
 
   Returns 1 on succes and 0 on failure.
 
   This will swap the Python interpreter thread state to gain access to
-  the underlying Python stream object. It **should** not be called from
+  the underlying Python stream object. It **should not** be called from
   within the same interpreter thread, as it locks the interpreter stat
   (and thus itself).
 
   Returns the current stream position or -1 if an error occured.
 
   This will swap the Python interpreter thread state to gain access to
-  the underlying Python stream object. It **should** not be called from
+  the underlying Python stream object. It **should not** be called from
   within the same interpreter thread, as it locks the interpreter stat
   (and thus itself).
 
   Returns 1 on success and 0 on failure.
 
   This will swap the Python interpreter thread state to gain access to
-  the underlying Python stream object. It **should** not be called from
+  the underlying Python stream object. It **should not** be called from
   within the same interpreter thread, as it locks the interpreter stat
   (and thus itself).
 

src/sdl/timemod.c

     if (!id)
     {
         DEBUG_P ("CALLBACK DEFUNCT");
-        goto retnopost;
+        return 0;
     }
     
     /* Wait for the removal */
     DEBUG_P ("WAITING FOR RUN");
     if (SDL_SemWait (timerdata->wait) == -1)
-        goto retnopost;
+        return 0;
     DEBUG_P ("GOT RUN SIGNAL");
 
 #ifdef WITH_THREAD
     PyEval_AcquireLock ();
     oldstate = PyThreadState_Swap (timerdata->thread);
 #endif
-  
+
+    DEBUG_P ("SWAPPED STATE");
+    if (timerdata->id == NULL)
+    {
+        DEBUG_P ("CALLBACK DEFUNCT");
+        goto ret;
+    }
+
     val = PyLong_FromUnsignedLong ((unsigned long)interval);
     if (timerdata->param)
         result = PyObject_CallObject (timerdata->callable, timerdata->param);
     }
 
 ret:
-    if (SDL_SemPost (timerdata->wait) == -1)
-    {
-        /* TODO */
-        DEBUG_P ("ERROR ON POST");
-    }
-    /* DEBUG_P ("POSTED AFTER RUN"); */
-retnopost:
 #ifdef WITH_THREAD
     PyThreadState_Swap (oldstate);
     PyEval_ReleaseLock ();
 #endif
-
+    if (timerdata->wait)
+    {
+        if (SDL_SemPost (timerdata->wait) == -1)
+        {
+            DEBUG_P ("ERROR ON POST IN CALLBACK");
+        }
+    }
     return retval;
 }
 
     _TimerData *data = (_TimerData*) p;
     if (!data)
         return;
-    
+
     if (data->id)
         SDL_RemoveTimer (data->id);
     data->id = NULL;
 static PyObject*
 _sdl_timeinit (PyObject *self)
 {
+    int ret;
     if (SDL_WasInit (SDL_INIT_TIMER))
         Py_RETURN_NONE;
 
-    if (SDL_InitSubSystem (SDL_INIT_TIMER) == -1)
+    Py_BEGIN_ALLOW_THREADS;
+    ret = SDL_InitSubSystem (SDL_INIT_TIMER);
+    Py_END_ALLOW_THREADS;
+
+    if (ret == -1)
     {
         PyErr_SetString (PyExc_PyGameError, SDL_GetError ());
         return NULL;
     Py_XDECREF (state->timerlist);
     state->timerlist = NULL;
 
+    Py_BEGIN_ALLOW_THREADS;
     if (SDL_WasInit (SDL_INIT_TIMER))
         SDL_QuitSubSystem (SDL_INIT_TIMER);
+    Py_END_ALLOW_THREADS;
     Py_RETURN_NONE;
 }
 
         PyErr_SetString (PyExc_ValueError, "invalid timer id");
         return NULL;
     }
-    
-    DEBUG_P ("WAITING FOR REMOVE SIGNAL");
-    if (SDL_SemWait (timerdata->wait) == -1)
-    {
-        PyErr_SetString (PyExc_PyGameError, SDL_GetError ());
-        return NULL;
-    }
-    DEBUG_P ("GOT REMOVE SIGNAL");
+
+    DEBUG_P ("REMOVING TIMER");
     SDL_RemoveTimer (timerdata->id);
     timerdata->id = NULL;
-    if (SDL_SemPost (timerdata->wait) == -1)
-    {
-        /* TODO */
-        DEBUG_P ("ERROR ON POST");
-    }
-    
+
     if (PySequence_DelItem (state->timerlist, pos) == -1)
         return NULL;
     
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.