Fix bug in the way an Event handles a bound thread.

This just keeps the (test) Event representation in sync with
the runtime Event representation, which is modified by

  https://googleplex-android-review.git.corp.google.com/#/c/platform/frameworks/ml/+/2880348/

Bug: 63905942
Test: vts
Change-Id: I2a6de4397c5e31e35cb3d02e241dd21452c21ca6
diff --git a/neuralnetworks/1.0/vts/functional/Event.cpp b/neuralnetworks/1.0/vts/functional/Event.cpp
index 0fab86b..67de4f5 100644
--- a/neuralnetworks/1.0/vts/functional/Event.cpp
+++ b/neuralnetworks/1.0/vts/functional/Event.cpp
@@ -10,9 +10,15 @@
 Event::Event() : mStatus(Status::WAITING) {}
 
 Event::~Event() {
-    if (mThread.joinable()) {
-        mThread.join();
-    }
+    // Note that we cannot call Event::join_thread from here: Event is
+    // intended to be reference counted, and it is possible that the
+    // reference count drops to zero in the bound thread, causing the
+    // bound thread to call this destructor. If a thread tries to join
+    // itself, it throws an exception, producing a message like the
+    // following:
+    //
+    //     terminating with uncaught exception of type std::__1::system_error:
+    //     thread::join failed: Resource deadlock would occur
 }
 
 Return<void> Event::notify(ReturnedStatus status) {
@@ -38,6 +44,7 @@
 Event::Status Event::wait() {
     std::unique_lock<std::mutex> lock(mMutex);
     mCondition.wait(lock, [this]{return mStatus != Status::WAITING;});
+    join_thread_locked();
     return mStatus;
 }
 
@@ -69,6 +76,17 @@
     return true;
 }
 
+void Event::join_thread() {
+    std::lock_guard<std::mutex> lock(mMutex);
+    join_thread_locked();
+}
+
+void Event::join_thread_locked() {
+    if (mThread.joinable()) {
+        mThread.join();
+    }
+}
+
 }  // namespace implementation
 }  // namespace V1_0
 }  // namespace neuralnetworks