Bluetooth: AsyncFdWatcher: Refactor timeout lock

Allow timeouts to change the timeout.
Add a unit test for this.

Test: Unit tests pass, Bluetooth starts and stops.
Change-Id: I1be8a18dd74a312175ec9c27de37213272650e8e
diff --git a/bluetooth/1.0/default/async_fd_watcher.cc b/bluetooth/1.0/default/async_fd_watcher.cc
index 9cd86f1..161a74a 100644
--- a/bluetooth/1.0/default/async_fd_watcher.cc
+++ b/bluetooth/1.0/default/async_fd_watcher.cc
@@ -140,9 +140,15 @@
 
     // Timeout.
     if (retval == 0) {
-      std::unique_lock<std::mutex> guard(timeout_mutex_);
-      if (timeout_ms_ > std::chrono::milliseconds(0) && timeout_cb_)
-        timeout_cb_();
+      // Allow the timeout callback to modify the timeout.
+      TimeoutCallback saved_cb;
+      {
+        std::unique_lock<std::mutex> guard(timeout_mutex_);
+        if (timeout_ms_ > std::chrono::milliseconds(0))
+          saved_cb = timeout_cb_;
+      }
+      if (saved_cb != nullptr)
+        saved_cb();
       continue;
     }