.NET SpinLock не выпускает Thread.BeginCriticalSection - PullRequest
1 голос
/ 05 апреля 2011

Используя рефлектор .NET, я обнаружил, что структура SpinLock имеет много случаев, когда она вызывает Thread.BeginCriticalRegion и не вызывает Thread.EndCriticalRegion .Например, в публичной функции SpinLock.Enter (ref bool lockTaken) (.NET 4.0):

// ...
Thread.BeginCriticalRegion();
if (Interlocked.CompareExchange(ref this.m_owner, managedThreadId, owner, ref lockTaken) == owner)
    return;  // <--- !!
Thread.EndCriticalRegion();
// ...

В другом случае SpinLock.Exit, кажется, вызывает Thread.EndCriticalRegion безвызвав Thread.BeginCriticalRegion .

public void Exit(bool useMemoryBarrier)
{
    if (this.IsThreadOwnerTrackingEnabled && !this.IsHeldByCurrentThread)
        throw ...

    if (useMemoryBarrier)
    {
        if (this.IsThreadOwnerTrackingEnabled)
            Interlocked.Exchange(ref this.m_owner, 0);
        else
            Interlocked.Decrement(ref this.m_owner);
    }
    else if (this.IsThreadOwnerTrackingEnabled)
        this.m_owner = 0;
    else
    {
        int owner = this.m_owner;
        this.m_owner = owner - 1;
    }
    Thread.EndCriticalRegion();   // <--- ??
}

Итак, возникает вопрос: возникают ли какие-либо проблемы из-за несбалансированности вызовов Begin / EndCriticalRegion?

1 Ответ

1 голос
/ 05 апреля 2011

Обратите внимание, что начальные / конечные вызовы do балансируют, если блокировка фактически снята, а затем снята с помощью вызова Exit (). Вызовы для маркировки критической области необходимы, чтобы CLR знала, что прерывания потока могут повредить при получении SpinLock. См. здесь для получения дополнительной информации.

...