layers: Wrap a unique_lock around chassis mutex

The default behavior is to return a lock that has acquired the mutex.
Overrides, such as thread_safety, may take a deferred lock. i.e. It
doesn't acquire the mutex. The goal here is to leverage RAII and SBRM
for lock management.

Change-Id: I274b1e44e62bf143898cca4bee63a6d76effce87
diff --git a/scripts/layer_chassis_generator.py b/scripts/layer_chassis_generator.py
index 4bc84c9..8bf1b10 100644
--- a/scripts/layer_chassis_generator.py
+++ b/scripts/layer_chassis_generator.py
@@ -267,8 +267,9 @@
         virtual ~ValidationObject() {};
 
         std::mutex validation_object_mutex;
-        virtual void write_lock() { validation_object_mutex.lock(); }
-        virtual void write_unlock() { validation_object_mutex.unlock(); }
+        virtual std::unique_lock<std::mutex> write_lock() {
+            return std::unique_lock<std::mutex>(validation_object_mutex);
+        }
 
         ValidationObject* GetValidationObject(std::vector<ValidationObject*>& object_dispatch, LayerObjectTypeId object_type) {
             for (auto validation_object : object_dispatch) {
@@ -580,22 +581,19 @@
     dispatch_key key = get_dispatch_key(instance);
     auto layer_data = GetLayerDataPtr(key, layer_data_map);
     """ + precallvalidate_loop + """
-        intercept->write_lock();
+        auto lock = intercept->write_lock();
         intercept->PreCallValidateDestroyInstance(instance, pAllocator);
-        intercept->write_unlock();
     }
     """ + precallrecord_loop + """
-        intercept->write_lock();
+        auto lock = intercept->write_lock();
         intercept->PreCallRecordDestroyInstance(instance, pAllocator);
-        intercept->write_unlock();
     }
 
     layer_data->instance_dispatch_table.DestroyInstance(instance, pAllocator);
 
     """ + postcallrecord_loop + """
-        intercept->write_lock();
+        auto lock = intercept->write_lock();
         intercept->PostCallRecordDestroyInstance(instance, pAllocator);
-        intercept->write_unlock();
     }
     // Clean up logging callback, if any
     while (layer_data->logging_messenger.size() > 0) {
@@ -646,15 +644,13 @@
 
     bool skip = false;
     for (auto intercept : instance_interceptor->object_dispatch) {
-        intercept->write_lock();
+        auto lock = intercept->write_lock();
         skip |= intercept->PreCallValidateCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
-        intercept->write_unlock();
         if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
     }
     for (auto intercept : instance_interceptor->object_dispatch) {
-        intercept->write_lock();
+        auto lock = intercept->write_lock();
         intercept->PreCallRecordCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
-        intercept->write_unlock();
     }
 
     VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
@@ -711,9 +707,8 @@
 #endif
 
     for (auto intercept : instance_interceptor->object_dispatch) {
-        intercept->write_lock();
+        auto lock = intercept->write_lock();
         intercept->PostCallRecordCreateDevice(gpu, pCreateInfo, pAllocator, pDevice, result);
-        intercept->write_unlock();
     }
 
     DeviceExtensionWhitelist(device_interceptor, pCreateInfo, *pDevice);
@@ -725,23 +720,20 @@
     dispatch_key key = get_dispatch_key(device);
     auto layer_data = GetLayerDataPtr(key, layer_data_map);
     """ + precallvalidate_loop + """
-        intercept->write_lock();
+        auto lock = intercept->write_lock();
         intercept->PreCallValidateDestroyDevice(device, pAllocator);
-        intercept->write_unlock();
     }
     """ + precallrecord_loop + """
-        intercept->write_lock();
+        auto lock = intercept->write_lock();
         intercept->PreCallRecordDestroyDevice(device, pAllocator);
-        intercept->write_unlock();
     }
     layer_debug_utils_destroy_device(device);
 
     layer_data->device_dispatch_table.DestroyDevice(device, pAllocator);
 
     """ + postcallrecord_loop + """
-        intercept->write_lock();
+        auto lock = intercept->write_lock();
         intercept->PostCallRecordDestroyDevice(device, pAllocator);
-        intercept->write_unlock();
     }
 
     for (auto item = layer_data->object_dispatch.begin(); item != layer_data->object_dispatch.end(); item++) {
@@ -756,21 +748,18 @@
                                                             VkDebugReportCallbackEXT *pCallback) {
     auto layer_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map);
     """ + precallvalidate_loop + """
-        intercept->write_lock();
+        auto lock = intercept->write_lock();
         intercept->PreCallValidateCreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback);
-        intercept->write_unlock();
     }
     """ + precallrecord_loop + """
-        intercept->write_lock();
+        auto lock = intercept->write_lock();
         intercept->PreCallRecordCreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback);
-        intercept->write_unlock();
     }
     VkResult result = DispatchCreateDebugReportCallbackEXT(layer_data, instance, pCreateInfo, pAllocator, pCallback);
     result = layer_create_report_callback(layer_data->report_data, false, pCreateInfo, pAllocator, pCallback);
     """ + postcallrecord_loop + """
-        intercept->write_lock();
+        auto lock = intercept->write_lock();
         intercept->PostCallRecordCreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback, result);
-        intercept->write_unlock();
     }
     return result;
 }
@@ -779,21 +768,18 @@
                                                          const VkAllocationCallbacks *pAllocator) {
     auto layer_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map);
     """ + precallvalidate_loop + """
-        intercept->write_lock();
+        auto lock = intercept->write_lock();
         intercept->PreCallValidateDestroyDebugReportCallbackEXT(instance, callback, pAllocator);
-        intercept->write_unlock();
     }
     """ + precallrecord_loop + """
-        intercept->write_lock();
+        auto lock = intercept->write_lock();
         intercept->PreCallRecordDestroyDebugReportCallbackEXT(instance, callback, pAllocator);
-        intercept->write_unlock();
     }
     DispatchDestroyDebugReportCallbackEXT(layer_data, instance, callback, pAllocator);
     layer_destroy_report_callback(layer_data->report_data, callback, pAllocator);
     """ + postcallrecord_loop + """
-        intercept->write_lock();
+        auto lock = intercept->write_lock();
         intercept->PostCallRecordDestroyDebugReportCallbackEXT(instance, callback, pAllocator);
-        intercept->write_unlock();
     }
 }"""
 
@@ -1082,17 +1068,15 @@
 
         # Generate pre-call validation source code
         self.appendSection('command', '    %s' % self.precallvalidate_loop)
-        self.appendSection('command', '        intercept->write_lock();')
+        self.appendSection('command', '        auto lock = intercept->write_lock();')
         self.appendSection('command', '        skip |= intercept->PreCallValidate%s(%s);' % (api_function_name[2:], paramstext))
-        self.appendSection('command', '        intercept->write_unlock();')
         self.appendSection('command', '        if (skip) %s' % return_map[resulttype.text])
         self.appendSection('command', '    }')
 
         # Generate pre-call state recording source code
         self.appendSection('command', '    %s' % self.precallrecord_loop)
-        self.appendSection('command', '        intercept->write_lock();')
+        self.appendSection('command', '        auto lock = intercept->write_lock();')
         self.appendSection('command', '        intercept->PreCallRecord%s(%s);' % (api_function_name[2:], paramstext))
-        self.appendSection('command', '        intercept->write_unlock();')
         self.appendSection('command', '    }')
 
         # Insert pre-dispatch debug utils function call
@@ -1117,9 +1101,8 @@
         returnparam = ''
         if (resulttype.text == 'VkResult'):
             returnparam = ', result'
-        self.appendSection('command', '        intercept->write_lock();')
+        self.appendSection('command', '        auto lock = intercept->write_lock();')
         self.appendSection('command', '        intercept->PostCallRecord%s(%s%s);' % (api_function_name[2:], paramstext, returnparam))
-        self.appendSection('command', '        intercept->write_unlock();')
         self.appendSection('command', '    }')
         # Return result variable, if any.
         if (resulttype.text != 'void'):