Bug 1133190 - Don't use auto_unlock in paths where lock is being destroyed. r=kinetik
authorPaul Adenot <paul@paul.cx>
Thu, 19 Feb 2015 19:35:06 +1300
changeset 229791 35b8aaad1312e40ae4ee57dc924cb47760742361
parent 229790 99f5101d6cf18479f300d29725026094db957673
child 229792 d3d919e4fdf4cc86e34d6f1d80557890c1e80a62
push id55804
push usermgregan@mozilla.com
push dateThu, 19 Feb 2015 06:35:35 +0000
treeherdermozilla-inbound@c841c87a7791 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik
bugs1133190
milestone38.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1133190 - Don't use auto_unlock in paths where lock is being destroyed. r=kinetik
media/libcubeb/src/cubeb_wasapi.cpp
--- a/media/libcubeb/src/cubeb_wasapi.cpp
+++ b/media/libcubeb/src/cubeb_wasapi.cpp
@@ -142,30 +142,16 @@ struct auto_lock {
   ~auto_lock()
   {
     lock->leave();
   }
 private:
   owned_critical_section * lock;
 };
 
-struct auto_unlock {
-  auto_unlock(owned_critical_section * lock)
-    : lock(lock)
-  {
-    lock->leave();
-  }
-  ~auto_unlock()
-  {
-    lock->enter();
-  }
-private:
-  owned_critical_section * lock;
-};
-
 struct auto_com {
   auto_com() {
     result = CoInitializeEx(NULL, COINIT_MULTITHREADED);
   }
   ~auto_com() {
     if (result == RPC_E_CHANGED_MODE) {
       // This is not an error, COM was not initialized by this function, so it is
       // not necessary to uninit it.
@@ -979,40 +965,40 @@ int setup_wasapi_stream(cubeb_stream * s
     return CUBEB_ERROR;
   }
 
   assert(!stm->client && "WASAPI stream already setup, close it first.");
 
   hr = get_default_endpoint(&device);
   if (FAILED(hr)) {
     LOG("Could not get default endpoint, error: %x\n", hr);
-    auto_unlock unlock(stm->stream_reset_lock);
+    stm->stream_reset_lock->leave();
     wasapi_stream_destroy(stm);
     return CUBEB_ERROR;
   }
 
   /* Get a client. We will get all other interfaces we need from
    * this pointer. */
   hr = device->Activate(__uuidof(IAudioClient),
                         CLSCTX_INPROC_SERVER,
                         NULL, (void **)&stm->client);
   SafeRelease(device);
   if (FAILED(hr)) {
     LOG("Could not activate the device to get an audio client: error: %x\n", hr);
-    auto_unlock unlock(stm->stream_reset_lock);
+    stm->stream_reset_lock->leave();
     wasapi_stream_destroy(stm);
     return CUBEB_ERROR;
   }
 
   /* We have to distinguish between the format the mixer uses,
    * and the format the stream we want to play uses. */
   hr = stm->client->GetMixFormat(&mix_format);
   if (FAILED(hr)) {
     LOG("Could not fetch current mix format from the audio client: error: %x\n", hr);
-    auto_unlock unlock(stm->stream_reset_lock);
+    stm->stream_reset_lock->leave();
     wasapi_stream_destroy(stm);
     return CUBEB_ERROR;
   }
 
   handle_channel_layout(stm, &mix_format, &stm->stream_params);
 
   /* Shared mode WASAPI always supports float32 sample format, so this
    * is safe. */
@@ -1027,72 +1013,72 @@ int setup_wasapi_stream(cubeb_stream * s
                                0,
                                mix_format,
                                NULL);
 
   CoTaskMemFree(mix_format);
 
   if (FAILED(hr)) {
     LOG("Unable to initialize audio client: %x.\n", hr);
-    auto_unlock unlock(stm->stream_reset_lock);
+    stm->stream_reset_lock->leave();
     wasapi_stream_destroy(stm);
     return CUBEB_ERROR;
   }
 
   hr = stm->client->GetBufferSize(&stm->buffer_frame_count);
   if (FAILED(hr)) {
     LOG("Could not get the buffer size from the client %x.\n", hr);
-    auto_unlock unlock(stm->stream_reset_lock);
+    stm->stream_reset_lock->leave();
     wasapi_stream_destroy(stm);
     return CUBEB_ERROR;
   }
 
   if (should_upmix(stm) || should_downmix(stm)) {
     stm->mix_buffer = (float *) malloc(frames_to_bytes_before_mix(stm, stm->buffer_frame_count));
   }
 
   hr = stm->client->SetEventHandle(stm->refill_event);
   if (FAILED(hr)) {
     LOG("Could set the event handle for the client %x.\n", hr);
-    auto_unlock unlock(stm->stream_reset_lock);
+    stm->stream_reset_lock->leave();
     wasapi_stream_destroy(stm);
     return CUBEB_ERROR;
   }
 
   hr = stm->client->GetService(__uuidof(IAudioRenderClient),
                                (void **)&stm->render_client);
   if (FAILED(hr)) {
     LOG("Could not get the render client %x.\n", hr);
-    auto_unlock unlock(stm->stream_reset_lock);
+    stm->stream_reset_lock->leave();
     wasapi_stream_destroy(stm);
     return CUBEB_ERROR;
   }
 
   hr = stm->client->GetService(__uuidof(IAudioStreamVolume),
                                (void **)&stm->audio_stream_volume);
   if (FAILED(hr)) {
     LOG("Could not get the IAudioStreamVolume %x.\n", hr);
-    auto_unlock unlock(stm->stream_reset_lock);
+    stm->stream_reset_lock->leave();
     wasapi_stream_destroy(stm);
     return CUBEB_ERROR;
   }
 
   /* If we are playing a mono stream, we only resample one channel,
    * and copy it over, so we are always resampling the number
    * of channels of the stream, not the number of channels
    * that WASAPI wants. */
   stm->resampler = cubeb_resampler_create(stm, stm->stream_params,
                                           stm->mix_params.rate,
                                           stm->data_callback,
                                           stm->buffer_frame_count,
                                           stm->user_ptr,
                                           CUBEB_RESAMPLER_QUALITY_DESKTOP);
   if (!stm->resampler) {
     LOG("Could not get a resampler\n");
-    auto_unlock unlock(stm->stream_reset_lock);
+    stm->stream_reset_lock->leave();
     wasapi_stream_destroy(stm);
     return CUBEB_ERROR;
   }
 
   return CUBEB_OK;
 }
 
 int
@@ -1244,18 +1230,19 @@ int stream_stop(cubeb_stream * stm, bool
     LOG("could not stop AudioClient\n");
   }
   if (was_running) {
     *was_running = hr == S_OK;
     assert(*was_running == !!stm->thread);
   }
 
   {
-    auto_unlock lock(stm->stream_reset_lock);
+    stm->stream_reset_lock->leave();
     stop_and_join_render_thread(stm);
+    stm->stream_reset_lock->enter();
   }
 
   if (SUCCEEDED(hr)) {
     stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STOPPED);
   }
 
   return FAILED(hr) ? CUBEB_ERROR : CUBEB_OK;
 }