layers: Make layer logging thread-safe

Some validation objects in the layer chassis may not need to lock
around validation/recording calls, leaving access to the debug report-
related data structures unprotected. Added a mutex to the
debug_report_data structure and the lock calls where they were
necessary.

Change-Id: I60938f73c53286808afac4df0f264c1b3bdefc25
diff --git a/layers/vk_layer_logging.h b/layers/vk_layer_logging.h
index 92146cb..02c6b42 100644
--- a/layers/vk_layer_logging.h
+++ b/layers/vk_layer_logging.h
@@ -32,6 +32,7 @@
 #include "vk_object_types.h"
 #include "vk_validation_error_messages.h"
 #include "vk_layer_dispatch_table.h"
+#include <mutex>
 #include <signal.h>
 #include <cinttypes>
 #include <stdarg.h>
@@ -91,8 +92,12 @@
     std::unordered_map<uint64_t, std::string> debugUtilsObjectNameMap;
     std::unordered_map<VkQueue, std::vector<LoggingLabelData>> debugUtilsQueueLabels;
     std::unordered_map<VkCommandBuffer, std::vector<LoggingLabelData>> debugUtilsCmdBufLabels;
+    // This mutex is defined as mutable since the normal usage for a debug report object is as 'const'. The mutable keyword allows
+    // the layers to continue this pattern, but also allows them to use/change this specific member for synchronization purposes.
+    mutable std::mutex debug_report_mutex;
 
     void DebugReportSetUtilsObjectName(const VkDebugUtilsObjectNameInfoEXT *pNameInfo) {
+        std::unique_lock<std::mutex> lock(debug_report_mutex);
         if (pNameInfo->pObjectName) {
             debugUtilsObjectNameMap.insert(
                 std::make_pair<uint64_t, std::string>((uint64_t &&) pNameInfo->objectHandle, pNameInfo->pObjectName));
@@ -102,6 +107,7 @@
     }
 
     void DebugReportSetMarkerObjectName(const VkDebugMarkerObjectNameInfoEXT *pNameInfo) {
+        std::unique_lock<std::mutex> lock(debug_report_mutex);
         if (pNameInfo->pObjectName) {
             debugObjectNameMap.insert(
                 std::make_pair<uint64_t, std::string>((uint64_t &&) pNameInfo->object, pNameInfo->pObjectName));
@@ -551,8 +557,10 @@
 
 static inline void layer_debug_utils_destroy_instance(debug_report_data *debug_data) {
     if (debug_data) {
+        std::unique_lock<std::mutex> lock(debug_data->debug_report_mutex);
         RemoveAllMessageCallbacks(debug_data, &debug_data->default_debug_callback_list);
         RemoveAllMessageCallbacks(debug_data, &debug_data->debug_callback_list);
+        lock.unlock();
         delete (debug_data);
     }
 }
@@ -569,6 +577,7 @@
 
 static inline void layer_destroy_messenger_callback(debug_report_data *debug_data, VkDebugUtilsMessengerEXT messenger,
                                                     const VkAllocationCallbacks *allocator) {
+    std::unique_lock<std::mutex> lock(debug_data->debug_report_mutex);
     RemoveDebugUtilsMessenger(debug_data, &debug_data->debug_callback_list, messenger);
     RemoveDebugUtilsMessenger(debug_data, &debug_data->default_debug_callback_list, messenger);
 }
@@ -577,6 +586,7 @@
                                                        const VkDebugUtilsMessengerCreateInfoEXT *create_info,
                                                        const VkAllocationCallbacks *allocator,
                                                        VkDebugUtilsMessengerEXT *messenger) {
+    std::unique_lock<std::mutex> lock(debug_data->debug_report_mutex);
     VkLayerDbgFunctionNode *pNewDbgFuncNode = (VkLayerDbgFunctionNode *)malloc(sizeof(VkLayerDbgFunctionNode));
     if (!pNewDbgFuncNode) return VK_ERROR_OUT_OF_HOST_MEMORY;
     memset(pNewDbgFuncNode, 0, sizeof(VkLayerDbgFunctionNode));
@@ -618,6 +628,7 @@
 
 static inline void layer_destroy_report_callback(debug_report_data *debug_data, VkDebugReportCallbackEXT callback,
                                                  const VkAllocationCallbacks *allocator) {
+    std::unique_lock<std::mutex> lock(debug_data->debug_report_mutex);
     RemoveDebugUtilsMessageCallback(debug_data, &debug_data->debug_callback_list, callback);
     RemoveDebugUtilsMessageCallback(debug_data, &debug_data->default_debug_callback_list, callback);
 }
@@ -625,6 +636,7 @@
 static inline VkResult layer_create_report_callback(debug_report_data *debug_data, bool default_callback,
                                                     const VkDebugReportCallbackCreateInfoEXT *create_info,
                                                     const VkAllocationCallbacks *allocator, VkDebugReportCallbackEXT *callback) {
+    std::unique_lock<std::mutex> lock(debug_data->debug_report_mutex);
     VkLayerDbgFunctionNode *pNewDbgFuncNode = (VkLayerDbgFunctionNode *)malloc(sizeof(VkLayerDbgFunctionNode));
     if (!pNewDbgFuncNode) {
         return VK_ERROR_OUT_OF_HOST_MEMORY;
@@ -910,6 +922,7 @@
 static inline bool log_msg(const debug_report_data *debug_data, VkFlags msg_flags, VkDebugReportObjectTypeEXT object_type,
                            uint64_t src_object, std::string vuid_text, const char *format, ...) {
     if (!debug_data) return false;
+    std::unique_lock<std::mutex> lock(debug_data->debug_report_mutex);
     VkFlags local_severity = 0;
     VkFlags local_type = 0;
     DebugReportFlagsToAnnotFlags(msg_flags, true, &local_severity, &local_type);
@@ -1088,6 +1101,7 @@
 
 static inline void BeginQueueDebugUtilsLabel(debug_report_data *report_data, VkQueue queue,
                                              const VkDebugUtilsLabelEXT *label_info) {
+    std::unique_lock<std::mutex> lock(report_data->debug_report_mutex);
     if (nullptr != label_info && nullptr != label_info->pLabelName) {
         auto label_iter = report_data->debugUtilsQueueLabels.find(queue);
         if (label_iter == report_data->debugUtilsQueueLabels.end()) {
@@ -1109,6 +1123,7 @@
 }
 
 static inline void EndQueueDebugUtilsLabel(debug_report_data *report_data, VkQueue queue) {
+    std::unique_lock<std::mutex> lock(report_data->debug_report_mutex);
     auto label_iter = report_data->debugUtilsQueueLabels.find(queue);
     if (label_iter != report_data->debugUtilsQueueLabels.end()) {
         // If the last thing was a label insert, we need to pop it off of the label vector before any
@@ -1126,6 +1141,7 @@
 
 static inline void InsertQueueDebugUtilsLabel(debug_report_data *report_data, VkQueue queue,
                                               const VkDebugUtilsLabelEXT *label_info) {
+    std::unique_lock<std::mutex> lock(report_data->debug_report_mutex);
     if (nullptr != label_info && nullptr != label_info->pLabelName) {
         auto label_iter = report_data->debugUtilsQueueLabels.find(queue);
         if (label_iter == report_data->debugUtilsQueueLabels.end()) {
@@ -1150,6 +1166,7 @@
 
 static inline void BeginCmdDebugUtilsLabel(debug_report_data *report_data, VkCommandBuffer command_buffer,
                                            const VkDebugUtilsLabelEXT *label_info) {
+    std::unique_lock<std::mutex> lock(report_data->debug_report_mutex);
     if (nullptr != label_info && nullptr != label_info->pLabelName) {
         auto label_iter = report_data->debugUtilsCmdBufLabels.find(command_buffer);
         if (label_iter == report_data->debugUtilsCmdBufLabels.end()) {
@@ -1171,6 +1188,7 @@
 }
 
 static inline void EndCmdDebugUtilsLabel(debug_report_data *report_data, VkCommandBuffer command_buffer) {
+    std::unique_lock<std::mutex> lock(report_data->debug_report_mutex);
     auto label_iter = report_data->debugUtilsCmdBufLabels.find(command_buffer);
     if (label_iter != report_data->debugUtilsCmdBufLabels.end()) {
         // If the last thing was a label insert, we need to pop it off of the label vector before any
@@ -1191,6 +1209,7 @@
 
 static inline void InsertCmdDebugUtilsLabel(debug_report_data *report_data, VkCommandBuffer command_buffer,
                                             const VkDebugUtilsLabelEXT *label_info) {
+    std::unique_lock<std::mutex> lock(report_data->debug_report_mutex);
     if (nullptr != label_info && nullptr != label_info->pLabelName) {
         auto label_iter = report_data->debugUtilsCmdBufLabels.find(command_buffer);
         if (label_iter == report_data->debugUtilsCmdBufLabels.end()) {