Пример #1
0
        /****************** 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);
        }
Пример #2
0
 /// <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);
     }
 }
Пример #3
0
        /// <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
        }
Пример #4
0
 /// <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);
 }
Пример #5
0
        /// <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);
        }