Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SpinLock throwing SynchronizationLockException

I am trying to use SpinLock, but even this most basic code in a single threaded Console app throws the following exception when I callSpinLock.Exit()

System.Threading.SynchronizationLockException was unhandled by user code
  Message=The calling thread does not hold the lock.  Source=mscorlib

Here is the entire source code...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ConsoleApplication48
{
    class Program
    {
        static readonly SpinLock SpinLock = new SpinLock();
        static void Main(string[] args)
        {
            bool lockTaken = false;
            try
            {
                SpinLock.Enter(ref lockTaken);
                if (lockTaken)
                    Console.WriteLine("Lock taken");
            }
            finally
            {
                if (lockTaken)
                    SpinLock.Exit();
            }
            Console.WriteLine("Done");
        }
    }
}
like image 382
Peter Morris Avatar asked Jun 27 '12 10:06

Peter Morris


1 Answers

SpinLock is a struct, and you are reading it from a readonly field. The C# spec says that in this case, in order to call a potentially mutating function, the struct must be copied to a mutable local variable. This happens under the covers.

Your calls to Enter and Exit happen on a fresh copy of your lock. For that reason, Enter is operating on an unlocked lock.

Don't make the SpinLock variable readonly because it is being mutated.

like image 50
usr Avatar answered Sep 28 '22 04:09

usr