message: Add a mutex to guard the global kernel registry. This was causing issues
  when XLA registers additional ops while OpKernel lookups were occurring.
diff: @@ -985,7 +985,10 @@ struct KernelRegistration {
  // This maps from 'op_type' + DeviceType to the set of KernelDefs and
  // factory functions for instantiating the OpKernel that matches the
  // KernelDef.
  -typedef std::unordered_multimap<string, KernelRegistration> KernelRegistry;
  +struct KernelRegistry {
  + mutex mu;
  + std::unordered_multimap<string, KernelRegistration> registry GUARDED_BY(mu);
  +};
  #if defined(_WIN32)
  static const char kKernelLibPattern[] = "libtfkernel*.dll";
  @@ -1113,9 +1116,12 @@ void OpKernelRegistrar::InitInternal(const KernelDef* kernel_def,
  // before some file libraries can initialize, which in turn crashes the
  // program flakily. Until we get rid of static initializers in kernel
  // registration mechanism, we have this workaround here.
  - reinterpret_cast<KernelRegistry*>(GlobalKernelRegistry())
  - ->emplace(key, KernelRegistration(*kernel_def, kernel_class_name,
  - std::move(factory)));
  + auto global_registry =
  + reinterpret_cast<KernelRegistry*>(GlobalKernelRegistry());
  + mutex_lock l(global_registry->mu);
  + global_registry->registry.emplace(
  + key,
  + KernelRegistration(*kernel_def, kernel_class_name, std::move(factory)));
  }
  delete kernel_def;
  }
  @@ -1144,7 +1150,9 @@ Status FindKernelRegistration(
  const string& label = GetNodeAttrString(node_attrs, kKernelAttr);
  const string key = Key(node_op, device_type, label);
  - auto regs = GlobalKernelRegistryTyped()->equal_range(key);
  + auto typed_registry = GlobalKernelRegistryTyped();
  + tf_shared_lock lock(typed_registry->mu);
  + auto regs = typed_registry->registry.equal_range(key);
  for (auto iter = regs.first; iter != regs.second; ++iter) {
  // If there is a kernel registered for the op and device_type,
  // check that the attrs match.
  @@ -1277,10 +1285,11 @@ KernelList GetAllRegisteredKernels() {
  KernelList GetFilteredRegisteredKernels(
  const std::function<bool(const KernelDef&)>& predicate) {
  - const KernelRegistry* const typed_registry = GlobalKernelRegistryTyped();
  + KernelRegistry* const typed_registry = GlobalKernelRegistryTyped();
  KernelList kernel_list;
  - kernel_list.mutable_kernel()->Reserve(typed_registry->size());
  - for (const auto& p : *typed_registry) {
  + tf_shared_lock lock(typed_registry->mu);
  + kernel_list.mutable_kernel()->Reserve(typed_registry->registry.size());
  + for (const auto& p : typed_registry->registry) {
  const KernelDef& kernel_def = p.second.def;
  if (predicate(kernel_def)) {
  *kernel_list.add_kernel() = kernel_def;
  @@ -1406,7 +1415,9 @@ bool FindArgInOp(StringPiece arg_name,
  } // namespace
  Status ValidateKernelRegistrations(const OpRegistryInterface& op_registry) {
  - for (const auto& key_registration : *GlobalKernelRegistryTyped()) {
  + auto typed_registry = GlobalKernelRegistryTyped();
  + tf_shared_lock lock(typed_registry->mu);
  + for (const auto& key_registration : typed_registry->registry) {
  const KernelDef& kernel_def(key_registration.second.def);
  const OpRegistrationData* op_reg_data;
  const Status status = op_registry.LookUp(kernel_def.op(), &op_reg_data);
  