displayconfig: Restrict the scope of death_service_mutex_

Multiple display config calls is causing deadlock when one
of them is waiting for commit and there are no free binder
threads.
- Allow perform calls to run concurrently.
- Execute service death callback exclusively.

Change-Id: I804e72d4961315c6fac13f5f967788b5bbc0febe
diff --git a/services/config/src/device_impl.cpp b/services/config/src/device_impl.cpp
index 4541368..c8f64dc 100644
--- a/services/config/src/device_impl.cpp
+++ b/services/config/src/device_impl.cpp
@@ -146,6 +146,7 @@
 
 void DeviceImpl::serviceDied(uint64_t client_handle,
                              const android::wp<::android::hidl::base::V1_0::IBase>& callback) {
+  std::lock_guard<std::shared_mutex> exclusive_lock(shared_mutex_);
   std::lock_guard<std::recursive_mutex> lock(death_service_mutex_);
   auto itr = display_config_map_.find(client_handle);
   std::shared_ptr<DeviceClientContext> client = itr->second;
@@ -989,16 +990,21 @@
 Return<void> DeviceImpl::perform(uint64_t client_handle, uint32_t op_code,
                                  const ByteStream &input_params, const HandleStream &input_handles,
                                  perform_cb _hidl_cb) {
+  std::shared_lock<std::shared_mutex> shared_lock(shared_mutex_);
   int32_t error = 0;
-  std::lock_guard<std::recursive_mutex> lock(death_service_mutex_);
-  auto itr = display_config_map_.find(client_handle);
-  if (itr == display_config_map_.end()) {
-    error = -EINVAL;
-    _hidl_cb(error, {}, {});
-    return Void();
+  std::shared_ptr<DeviceClientContext> client = nullptr;
+
+  {
+    std::lock_guard<std::recursive_mutex> lock(death_service_mutex_);
+    auto itr = display_config_map_.find(client_handle);
+    if (itr == display_config_map_.end()) {
+      error = -EINVAL;
+      _hidl_cb(error, {}, {});
+      return Void();
+    }
+    client = itr->second;
   }
 
-  std::shared_ptr<DeviceClientContext> client = itr->second;
   if (!client) {
     error = -EINVAL;
     _hidl_cb(error, {}, {});
diff --git a/services/config/src/device_impl.h b/services/config/src/device_impl.h
index cf60366..3433d05 100644
--- a/services/config/src/device_impl.h
+++ b/services/config/src/device_impl.h
@@ -74,6 +74,7 @@
 #include <utility>
 #include <string>
 #include <vector>
+#include <shared_mutex>
 
 #include "opcode_types.h"
 
@@ -187,6 +188,7 @@
   std::map<uint64_t, std::shared_ptr<DeviceClientContext>> display_config_map_;
   uint64_t client_id_ = 0;
   std::recursive_mutex death_service_mutex_;
+  std::shared_mutex shared_mutex_;
   static DeviceImpl *device_obj_;
   static std::mutex device_lock_;
 };