mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-19 22:05:58 +00:00
glwindow/winrt: Add warning message if window is being closed from a UI thread
All UI elements will follow Single-Threaded Apartments (STA) model. As a result, we should access them from dedicated UI thread. Due to the nature of the threading model, ANGLE will wait the UI thread while closing internal window/swapchain objects. A problem here is that when destroying GstGLWindow from the UI thread, it will wait GstGLContext's internal thread. Meanwhile, the GstGLContext's internal thread will be blocked because ANGLE wants to access the UI thread. That will cause a deadlock or exceptions. In short, application should not try to call gst_element_set_state(pipeline, GST_STATE_NULL) from a UI thread. That's a limitation of current implementation. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/745>
This commit is contained in:
parent
bdf73569f8
commit
579db691ed
1 changed files with 55 additions and 1 deletions
|
@ -331,6 +331,27 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
GetHasThreadAccess (bool &has_access)
|
||||
{
|
||||
HRESULT hr;
|
||||
boolean val;
|
||||
|
||||
if (!isValid_ || !dispatcher_)
|
||||
return E_FAIL;
|
||||
|
||||
hr = dispatcher_->get_HasThreadAccess (&val);
|
||||
if (FAILED (hr))
|
||||
return hr;
|
||||
|
||||
if (val)
|
||||
has_access = true;
|
||||
else
|
||||
has_access = false;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
private:
|
||||
bool
|
||||
registerSizeChangedHandlerForCoreWindow (GstGLWindow * window)
|
||||
|
@ -500,6 +521,7 @@ static guintptr gst_gl_window_winrt_egl_get_window_handle (GstGLWindow *
|
|||
static void gst_gl_window_winrt_egl_set_window_handle (GstGLWindow * window,
|
||||
guintptr handle);
|
||||
static void gst_gl_window_winrt_egl_show (GstGLWindow * window);
|
||||
static void gst_gl_window_winrt_egl_quit (GstGLWindow * window);
|
||||
|
||||
static void
|
||||
gst_gl_window_winrt_egl_class_init (GstGLWindowWinRTEGLClass * klass)
|
||||
|
@ -518,6 +540,8 @@ gst_gl_window_winrt_egl_class_init (GstGLWindowWinRTEGLClass * klass)
|
|||
GST_DEBUG_FUNCPTR (gst_gl_window_winrt_egl_set_window_handle);
|
||||
window_class->show =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_winrt_egl_show);
|
||||
window_class->quit =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_winrt_egl_quit);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -664,4 +688,34 @@ gst_gl_window_winrt_egl_on_resize (GstGLWindow * window,
|
|||
g_mutex_unlock (&priv->event_lock);
|
||||
|
||||
gst_gl_window_resize (window, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_window_winrt_egl_quit (GstGLWindow * window)
|
||||
{
|
||||
GstGLWindowWinRTEGL *window_egl = GST_GL_WINDOW_WINRT_EGL (window);
|
||||
GstGLWindowWinRTEGLPrivate *priv = window_egl->priv;
|
||||
|
||||
if (priv->resize_handler) {
|
||||
HRESULT hr;
|
||||
bool is_dispatcher_thread = false;
|
||||
|
||||
hr = priv->resize_handler->GetHasThreadAccess (is_dispatcher_thread);
|
||||
if (SUCCEEDED (hr) && is_dispatcher_thread) {
|
||||
/* In GstGLContext::destroy_context() -> eglDestroySurface(),
|
||||
* ANGLE will wait a UI thread for its own operations to be called
|
||||
* from the thread. Note that gst_gl_context_egl_destroy_context() will be
|
||||
* called from GstGLContext's internal GL thread.
|
||||
*
|
||||
* A problem is that if GstGLWindow is being closed from the UI thread,
|
||||
* ANGLE cannot access the UI thread as current thread is the thread.
|
||||
*/
|
||||
GST_ERROR_OBJECT (window,
|
||||
"Closing from a UI thread might cause a deadlock or crash");
|
||||
|
||||
g_warning ("GstGLWindowWinRTEGL should be closed from non-UI thread");
|
||||
}
|
||||
}
|
||||
|
||||
GST_GL_WINDOW_CLASS (parent_class)->quit (window);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue