0

I have a state variable whose fields of interest are thread-safe and kept fresh using a ReaderWriterLockSlim.I have fine-grained the access to all fields since i use them somewhere else separately.

While for individual access of fields it works fine , i also need to make a couple of operations atomic.In this case do i need an additional lock ?

I have a state variable that already contains thread-safe fields:

internal class State {

        private ReaderWriterLockSlim lck = new ReaderWriterLockSlim();

        private bool cmd_PopUp;

        private bool cmd_Shutdown;
        private bool cmd_Delay;



        public bool CMD_PopUp {
            get {
                try {
                    this.lck.EnterReadLock();
                    return this.cmd_PopUp;
                } finally {

                    this.lck.ExitReadLock();
                }

            }
            set {
                try {
                    this.lck.EnterWriteLock();
                    this.cmd_PopUp = value;
                } finally {

                    this.lck.ExitWriteLock();
                }
            }

        }

 //same goes for the other booleans
}

I already have this thread-safe and also i am ensuring the thread reads from the memory not from local cache.However i need multiple operations to be done atomic.

Atomic operations

public async Task Run(State state)
{

     while(true)
        {
        //do i need a lock here
                        if (state.CMD_Delay) {
                            state.CMD_Delay = false;
                            state.CMD_PopUp = false;
        //end of potential lock ?
                        } else if (state.CMD_Shutdown) { //same here
                            state.CMD_PopUp = false;
                            state.CMD_Shutdown = false;
                            await SomeAction();
                        }
        }
}

As you can see in my while i have an if-else where i need the group of operations to be atomic .Should i use an additional lock or is there some other lightweight solution ?

Bercovici Adrian
  • 8,794
  • 17
  • 73
  • 152

1 Answers1

1

It would make the most sense to me to re-use your existing lock:

internal class State
{
  ...
  public void SetDelayState()
  {
    try {
      this.lck.EnterWriteLock();
      this.cmd_Delay = false;
      this.cmd_PopUp = false;
    } finally {
      this.lck.ExitWriteLock();
    }
  }
  public void SetShutdownState()
  {
    try {
      this.lck.EnterWriteLock();
      this.cmd_PopUp = false;
      this.cmd_Shutdown = false;
    } finally {
      this.lck.ExitWriteLock();
    }
  }
}

In other words, move all atomic operations to be members of your State type.

Side note: you almost certainly do not need a reader/writer lock. Reader/writer locks should only be used when all of the following are true:

  • Some code paths are read-only and others are read/write.
  • Readers far outnumber writers.
  • There are a large number of consecutive readers.

If any of those are not true, then lock is the better choice.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • In my scenario readers outnumber writers (though i wouldn't say "far") , readers perform constant reads (continously -infinite loop) at different time intervals , and yes there are some read-only paths and others are read-write. – Bercovici Adrian Jun 05 '19 at 11:38