Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7478e201 authored by Martin Brabham's avatar Martin Brabham Committed by android-build-merger
Browse files

Merge "DO NOT MERGE: osi: Offload mutex pointer to local scope" into oc-dev

am: 61aa0961

Change-Id: Ic593d9a4c421539181402c39860db5771a8f1417
parents a4616bb2 61aa0961
Loading
Loading
Loading
Loading
+11 −5
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ struct alarm_t {
  // potentially long-running callback is executing. |alarm_cancel| uses this
  // mutex to provide a guarantee to its caller that the callback will not be
  // in progress when it returns.
  std::recursive_mutex* callback_mutex;
  std::shared_ptr<std::recursive_mutex> callback_mutex;
  period_ms_t creation_time;
  period_ms_t period;
  period_ms_t deadline;
@@ -155,7 +155,8 @@ static alarm_t* alarm_new_internal(const char* name, bool is_periodic) {

  alarm_t* ret = static_cast<alarm_t*>(osi_calloc(sizeof(alarm_t)));

  ret->callback_mutex = new std::recursive_mutex;
  std::shared_ptr<std::recursive_mutex> ptr(new std::recursive_mutex());
  ret->callback_mutex = ptr;
  ret->is_periodic = is_periodic;
  ret->stats.name = osi_strdup(name);
  // NOTE: The stats were reset by osi_calloc() above
@@ -167,7 +168,7 @@ void alarm_free(alarm_t* alarm) {
  if (!alarm) return;

  alarm_cancel(alarm);
  delete alarm->callback_mutex;

  osi_free((void*)alarm->stats.name);
  osi_free(alarm);
}
@@ -218,13 +219,15 @@ void alarm_cancel(alarm_t* alarm) {
  CHECK(alarms != NULL);
  if (!alarm) return;

  std::shared_ptr<std::recursive_mutex> local_mutex_ref;
  {
    std::lock_guard<std::mutex> lock(alarms_mutex);
    local_mutex_ref = alarm->callback_mutex;
    alarm_cancel_internal(alarm);
  }

  // If the callback for |alarm| is in progress, wait here until it completes.
  std::lock_guard<std::recursive_mutex> lock(*alarm->callback_mutex);
  std::lock_guard<std::recursive_mutex> lock(*local_mutex_ref);
}

// Internal implementation of canceling an alarm.
@@ -561,7 +564,10 @@ static void alarm_queue_ready(fixed_queue_t* queue, UNUSED_ATTR void* context) {
    alarm->queue = NULL;
  }

  std::lock_guard<std::recursive_mutex> cb_lock(*alarm->callback_mutex);
  // Increment the reference count of the mutex so it doesn't get freed
  // before the callback gets finished executing.
  std::shared_ptr<std::recursive_mutex> local_mutex_ref = alarm->callback_mutex;
  std::lock_guard<std::recursive_mutex> cb_lock(*local_mutex_ref);
  lock.unlock();

  // Update the statistics
+14 −0
Original line number Diff line number Diff line
@@ -451,3 +451,17 @@ TEST_F(AlarmTest, test_callback_free_race) {
  }
  alarm_cleanup();
}

static void remove_cb(void* data) {
  alarm_free((alarm_t*)data);
  semaphore_post(semaphore);
}

TEST_F(AlarmTest, test_delete_during_callback) {
  for (int i = 0; i < 1000; ++i) {
    alarm_t* alarm = alarm_new("alarm_test.test_delete_during_callback");
    alarm_set(alarm, 0, remove_cb, alarm);
    semaphore_wait(semaphore);
  }
  alarm_cleanup();
}