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

Commit 7c2acd11 authored by Ytai Ben-Tsvi's avatar Ytai Ben-Tsvi
Browse files

Do not hold the lock while invoking callbacks

Holding the lock creates a burden on the client, so easier to handle
here.

Test: Manual verification using logs.
Bug: 188502620
Change-Id: I1b3a417315bd05bd421b8d643fd15f832faace02
parent c29bad64
Loading
Loading
Loading
Loading
+26 −9
Original line number Diff line number Diff line
@@ -88,6 +88,8 @@ SpatializerPoseController::SpatializerPoseController(Listener* listener,
      })),
      mThread([this, maxUpdatePeriod] {
          while (true) {
              Pose3f headToStage;
              std::optional<HeadTrackingMode> modeIfChanged;
              {
                  std::unique_lock lock(mMutex);
                  mCondVar.wait_for(lock, maxUpdatePeriod,
@@ -96,7 +98,19 @@ SpatializerPoseController::SpatializerPoseController(Listener* listener,
                      ALOGV("Exiting thread");
                      return;
                  }
                  calculate_l();

                  // Calculate.
                  std::tie(headToStage, modeIfChanged) = calculate_l();
              }

              // Invoke the callbacks outside the lock.
              mListener->onHeadToStagePose(headToStage);
              if (modeIfChanged) {
                  mListener->onActualModeChange(modeIfChanged.value());
              }

              {
                  std::lock_guard lock(mMutex);
                  if (!mCalculated) {
                      mCalculated = true;
                      mCondVar.notify_all();
@@ -185,17 +199,20 @@ void SpatializerPoseController::waitUntilCalculated() {
    mCondVar.wait(lock, [this] { return mCalculated; });
}

void SpatializerPoseController::calculate_l() {
std::tuple<media::Pose3f, std::optional<media::HeadTrackingMode>>
SpatializerPoseController::calculate_l() {
    Pose3f headToStage;
    HeadTrackingMode mode;
    std::optional<media::HeadTrackingMode> modeIfChanged;

    mProcessor->calculate(elapsedRealtimeNano());
    headToStage = mProcessor->getHeadToStagePose();
    mode = mProcessor->getActualMode();
    mListener->onHeadToStagePose(headToStage);
    if (!mActualMode.has_value() || mActualMode.value() != mode) {
        mActualMode = mode;
        mListener->onActualModeChange(mode);
        modeIfChanged = mode;
    }
    return std::make_tuple(headToStage, modeIfChanged);
}

void SpatializerPoseController::recenter() {
+8 −6
Original line number Diff line number Diff line
@@ -38,15 +38,13 @@ namespace android {
 * - By setting a timeout in the ctor, a calculation will be triggered after the timeout elapsed
 *   from the last calculateAsync() call.
 *
 * This class is thread-safe. Callbacks are invoked with the lock held, so it is illegal to call
 * into this module from the callbacks.
 * This class is thread-safe.
 */
class SpatializerPoseController : private media::SensorPoseProvider::Listener {
  public:
    /**
     * Listener interface for getting pose and mode updates.
     * Methods will always be invoked from a designated thread. Calling into the parent class from
     * within the callbacks is disallowed (will result in a deadlock).
     * Methods will always be invoked from a designated thread.
     */
    class Listener {
      public:
@@ -109,7 +107,7 @@ class SpatializerPoseController : private media::SensorPoseProvider::Listener {

    /**
     * Blocks until calculation and invocation of the respective callbacks has happened at least
     * once.
     * once. Do not call from within callbacks.
     */
    void waitUntilCalculated();

@@ -131,7 +129,11 @@ class SpatializerPoseController : private media::SensorPoseProvider::Listener {
    void onPose(int64_t timestamp, int32_t sensor, const media::Pose3f& pose,
                const std::optional<media::Twist3f>& twist) override;

    void calculate_l();
    /**
     * Calculates the new outputs and updates internal state. Must be called with the lock held.
     * Returns values that should be passed to the respective callbacks.
     */
    std::tuple<media::Pose3f, std::optional<media::HeadTrackingMode>> calculate_l();
};

}  // namespace android