Source/NFX/OS/ManyReadersOneWriterSynchronizer.cs
/// <summary>
/// Obtains a write lock returning true on success. Only one thread may hold a write lock at a time,
/// and noone else can obtain a read lock until the write lock is released.
/// False is returned if cancel func was supplied and returned true to cancel-out the waiting
/// </summary>
Obtains a write lock returning true on success. Only one thread may hold a write lock at a time,
and noone else can obtain a read lock until the write lock is released.
False is returned if cancel func was supplied and returned true to cancel-out the waiting
Obtains a write lock returning true on success . Only one thread may hold a write lock at a time and noone else can obtain a read lock until the write lock is released . False is returned if cancel func was supplied and returned true to cancel - out the waiting
public bool GetWriteLock(Func<object, bool> cancel = null, object cancelContext = null)
      {
          int pauseCount = 0;
          Interlocked.Increment(ref m_WaitingWriters);
          while(true)
          {
            long current = Interlocked.CompareExchange(ref m_Readers, long.MinValue, 0);
            if (current==0)
            {
              Interlocked.Decrement(ref m_WaitingWriters);
              return true;
            }
            if (pauseCount<PAUSE_COUNT_PER_BATCH)
            {
                  var tightWait = MULTI_CPU && Thread.VolatileRead(ref m_WaitingWriters) < CPU_COUNT;
                  if (tightWait)
                    tightOnePause(pauseCount);
                  else
                    Thread.Sleep(1);
                  pauseCount++;
                  continue;
            }
            pauseCount = 0;
            if (cancel!=null)
            {
               var canceled = false;
                try
                {
                   canceled = cancel(cancelContext);
                }
                catch
                {
                   Interlocked.Decrement(ref m_WaitingWriters);
                   throw;
                }
                if (canceled)
                {
                  Interlocked.Decrement(ref m_WaitingWriters);
                  return false;
                }
            }
            Thread.Sleep(MIN_SLEEP_MS + (Thread.CurrentThread.GetHashCode() & 0xf));
          }
      }
public bool GetWriteLock ( Func < object , bool > cancel = null , object cancelContext = null ) { int pauseCount = 0 ; Interlocked . Increment ( ref m_WaitingWriters ) ; while ( true ) { long current = Interlocked . CompareExchange ( ref m_Readers , long . MinValue , 0 ) ; if ( current == 0 ) { Interlocked . Decrement ( ref m_WaitingWriters ) ; return true ; } if ( pauseCount < PAUSE_COUNT_PER_BATCH ) { var tightWait = MULTI_CPU && Thread . VolatileRead ( ref m_WaitingWriters ) < CPU_COUNT ; if ( tightWait ) tightOnePause ( pauseCount ) ; else Thread . Sleep ( 1 ) ; pauseCount ++ ; continue ; } pauseCount = 0 ; if ( cancel != null ) { var canceled = false ; try { canceled = cancel ( cancelContext ) ; } catch { Interlocked . Decrement ( ref m_WaitingWriters ) ; throw ; } if ( canceled ) { Interlocked . Decrement ( ref m_WaitingWriters ) ; return false ; } } Thread . Sleep ( MIN_SLEEP_MS + ( Thread . CurrentThread . GetHashCode ( ) & 0xf ) ) ; } }
Obtains a write lock returning true on success.
Obtains a write lock returning true on success .
//lock taken //severe contention //lock failed
cancel
Func<object, bool>
cancelContext
object