message: Avoid race condition between ReadVariableOp and ScatterUpdateVariableOp.
diff: @@ -140,20 +140,28 @@ void ReadVariableOp::Compute(OpKernelContext* ctx) {
  status.ToString()));
  core::ScopedUnref s(variable);
  + {
  + tf_shared_lock ml(*variable->mu());
  // We're acquiring a reference to the underlying buffer while
  // holding a shared lock to guarantee ordering of reads and
  - // writes.
  - tf_shared_lock ml(*variable->mu());
  + // writes when in copy-on-write mode.
  + if (!variable->copy_on_read_mode.load()) {
  const Tensor* t = variable->tensor();
  - OP_REQUIRES(ctx, dtype_ == t->dtype(),
  + OP_REQUIRES(
  + ctx, dtype_ == t->dtype(),
  errors::InvalidArgument(
  "Trying to read variable with wrong dtype. Expected ",
  DataTypeString(dtype_), " got ", DataTypeString(t->dtype())));
  - if (variable->copy_on_read_mode.load()) {
  - OP_REQUIRES_OK(ctx, CopyVariable(0, ctx, t));
  - } else {
  ctx->set_output(0, *t);
  + return;
  + }
  }
  + // Note: no need to check copy_on_read_mode again here as it only changes from
  + // false to true, never the other way around. We here do the copy under an
  + // exclusive lock to avoid racing writes.
  + mutex_lock ml(*variable->mu());
  + const Tensor* t = variable->tensor();
  + OP_REQUIRES_OK(ctx, CopyVariable(0, ctx, t));
  }
  ReadVariablesOp::ReadVariablesOp(OpKernelConstruction* c) : OpKernel(c) {
  