/****************** thread_lock_node 相关 **********************/ /// <summary> /// 从该线程的ThreadLockNode链表中选出当前读写锁对应的那个节点 /// </summary> /// <param name="dontAllocate">如果没有找到节点,是否不要创建</param> /// <returns>找到的节点</returns> private ThreadLockNode GetThreadLockNode(bool dontAllocate) { ThreadLockNode rwc = thread_tln; ThreadLockNode empty = null; while (rwc != null) { if (rwc.lock_id == this.lock_id) { return(rwc); } if (!dontAllocate && empty == null && IsRWEntryEmpty(rwc)) { empty = rwc; } rwc = rwc.next; } if (dontAllocate) { return(null); } if (empty == null) { empty = new ThreadLockNode(); empty.next = thread_tln; thread_tln = empty; } empty.lock_id = this.lock_id; return(empty); }
/// <summary> /// 当前线程是否还没有获取该锁 /// </summary> /// <param name="thread_lock_node">线程读写锁节点thread_lock_node</param> /// <returns></returns> private static bool IsRWEntryEmpty(ThreadLockNode thread_lock_node) { if (thread_lock_node.lock_id == 0) // 初始节点是无意义的空节点 { return(true); } else if (thread_lock_node.status == ThreadLockStatus.UNLOCK) // 当前没有占有该锁(曾经占有过) { return(true); } else { return(false); } }
/// <summary> /// 释放读锁 /// </summary> public void ExitReadLock() { ThreadLockNode thread_lock_node = null; EnterInterSpanLock(); thread_lock_node = GetThreadLockNode(true); if (thread_lock_node == null || thread_lock_node.status != ThreadLockStatus.READING) { ExitInterSpanLock(); throw new Exception("mis match read"); } --thread_count; thread_lock_node.status = ThreadLockStatus.UNLOCK; ExitAndWakeUpAppropriateWaiters(); // 唤醒合适的waiters }
/// <summary> /// thread_lock_node 是否仍对应当前读写锁 /// </summary> /// <param name="thread_lock_node"></param> /// <returns></returns> private bool IsRwHashEntryChanged(ThreadLockNode thread_lock_node) { return(thread_lock_node.lock_id != this.lock_id); }
/// <summary> /// 请求读锁核心逻辑 /// </summary> /// <param name="timeout">超时时限</param> /// <returns>是否成功</returns> private bool TryEnterReadLockCore(TimeoutTracker timeout) { ThreadLockNode thread_lock_node = null; int id = Thread.CurrentThread.ManagedThreadId; if (id == write_lock_thread_id) { // 不允许读锁直接降级为写锁 throw new Exception("Not allow read after write"); } EnterInterSpanLock(); thread_lock_node = GetThreadLockNode(false); if (thread_lock_node.status == ThreadLockStatus.READING) { // 已有读锁,不允许重入 ExitInterSpanLock(); throw new Exception("Not allow recursive read"); } else if (id == upgrade_lock_thread_id) { // 以获取可升级读锁的线程请求普通读锁,可以直接拿到锁(不会释放原来的可升级读锁) thread_lock_node.status = ThreadLockStatus.READING; thread_count++; ExitInterSpanLock(); return(true); } bool return_value = true; int spin_count = 0; for (; ;) { // 正常获取读锁 if (thread_count < MAX_READER) { thread_count++; thread_lock_node.status = ThreadLockStatus.READING; break; } // 自旋等待 if (spin_count < Maxspin_count) { ExitInterSpanLock(); if (timeout.IsExpired) { return(false); } spin_count++; Thread.SpinWait(spin_count); EnterInterSpanLock(); if (IsRwHashEntryChanged(thread_lock_node)) { thread_lock_node = GetThreadLockNode(false); } continue; } // 设置 ManualResetEvent 等待 if (readEvent == null) { LazyCreateEvent(ref readEvent, false); if (IsRwHashEntryChanged(thread_lock_node)) { thread_lock_node = GetThreadLockNode(false); } continue; } return_value = WaitOnEvent(readEvent, ref numReadWaiters, timeout); if (!return_value) { return(false); } if (IsRwHashEntryChanged(thread_lock_node)) { thread_lock_node = GetThreadLockNode(false); } } ExitInterSpanLock(); return(return_value); }