wasapi2: Fix potential crash on device activation failure
authorSeungha Yang <seungha@centricular.com>
Thu, 16 Mar 2023 14:09:53 +0000 (23:09 +0900)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Sat, 18 Mar 2023 02:01:30 +0000 (02:01 +0000)
The activation object is live in COM thread already and therefore
self refcount hack is pointless.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4207>

subprojects/gst-plugins-bad/sys/wasapi2/gstwasapi2client.cpp

index b2d1ac8..72bcc83 100644 (file)
@@ -144,7 +144,6 @@ public:
     client = (GstWasapi2Client *) g_weak_ref_get (&listener_);
 
     if (!client) {
-      this->Release ();
       GST_WARNING ("No listener was configured");
       return S_OK;
     }
@@ -177,8 +176,6 @@ public:
      * by passed IAudioClient handle via gst_wasapi2_client_on_device_activated
      */
 
-    this->Release ();
-
     return S_OK;
   }
 
@@ -231,17 +228,6 @@ public:
       hr = work_item->Invoke ();
     }
 
-    /* We should hold activator object until activation callback has executed,
-     * because OS doesn't hold reference of this callback COM object.
-     * otherwise access violation would happen
-     * See https://docs.microsoft.com/en-us/windows/win32/api/mmdeviceapi/nf-mmdeviceapi-activateaudiointerfaceasync
-     *
-     * This reference count will be decreased by self later on callback,
-     * which will be called from device worker thread.
-     */
-    if (gst_wasapi2_result (hr))
-      this->AddRef ();
-
     return hr;
   }
 
@@ -404,9 +390,6 @@ static void
 gst_wasapi2_client_constructed (GObject * object)
 {
   GstWasapi2Client *self = GST_WASAPI2_CLIENT (object);
-  /* *INDENT-OFF* */
-  ComPtr<GstWasapiDeviceActivator> activator;
-  /* *INDENT-ON* */
 
   /* Create a new thread to ensure that COM thread can be MTA thread.
    * We cannot ensure whether CoInitializeEx() was called outside of here for
@@ -959,6 +942,10 @@ run_loop:
 
   g_main_context_pop_thread_default (self->context);
 
+  /* Wait for pending async op if any */
+  if (self->dispatcher)
+    gst_wasapi2_client_ensure_activation (self);
+
   GST_WASAPI2_CLEAR_COM (self->audio_client);
 
   /* Reset explicitly to ensure that it happens before