예제 #1
0
        /// <summary>
        /// 释放所有命令
        /// </summary>
        /// <param name="head"></param>
        /// <param name="end"></param>
        /// <param name="startIndex"></param>
        /// <returns></returns>
        internal ClientCommand.CommandBase Free(ClientCommand.CommandBase head, ClientCommand.CommandBase end, int startIndex)
        {
            DisposeTimeout();
            bool isNext = false;

            freeEndIndexLock.EnterSleepFlag();
            try
            {
                foreach (CommandLink[] array in arrays)
                {
                    if (isNext)
                    {
                        if (array == null)
                        {
                            break;
                        }
                        for (startIndex = array.Length; startIndex != 0;)
                        {
                            ClientCommand.Command command = array[--startIndex].Command;
                            if (command != null)
                            {
                                array[startIndex].Command = null;
                                if (head == null)
                                {
                                    head = end = command;
                                }
                                else
                                {
                                    end.LinkNext = command;
                                    end          = command;
                                }
                            }
                        }
                    }
                    else
                    {
                        isNext = true;
                        do
                        {
                            ClientCommand.Command command = array[startIndex].Command;
                            if (command != null)
                            {
                                array[startIndex].Command = null;
                                if (head == null)
                                {
                                    head = end = command;
                                }
                                else
                                {
                                    end.LinkNext = command;
                                    end          = command;
                                }
                            }
                        }while (++startIndex != array.Length);
                    }
                }
            }
            finally { freeEndIndexLock.ExitSleepFlag(); }
            return(head);
        }
예제 #2
0
        /// <summary>
        /// 获取客户端命令
        /// </summary>
        /// <param name="index">客户端命令索引位置</param>
        /// <returns>客户端命令</returns>
        internal ClientCommand.Command GetCommand(int index)
        {
            if (keepCallbackCommandIndex == index)
            {
                return(keepCallbackCommand);
            }
            ClientCommand.Command command;
            int arrayIndex = index >> bitSize;

            if (arrayIndex == 0)
            {
                while (System.Threading.Interlocked.CompareExchange(ref freeEndIndexLock, 1, 0) != 0)
                {
                    AutoCSer.Threading.ThreadYield.YieldOnly();
                }
                switch (Array[index].Get(commandCount, out command))
                {
                case 0:
                    arrays[freeEndIndex >> bitSize][freeEndIndex & arraySizeAnd].Next = index;
                    freeEndIndex = index;
                    System.Threading.Interlocked.Exchange(ref freeEndIndexLock, 0);
                    return(command);

                case 1:
                    System.Threading.Interlocked.Exchange(ref freeEndIndexLock, 0);
                    keepCallbackCommand      = command;
                    keepCallbackCommandIndex = index;
                    return(command);

                default: System.Threading.Interlocked.Exchange(ref freeEndIndexLock, 0); return(null);
                }
            }
            if (arrayIndex != getArrayIndex)
            {
                getArray = arrays[getArrayIndex = arrayIndex];
            }
            int commandIndex = index & arraySizeAnd;

            while (System.Threading.Interlocked.CompareExchange(ref freeEndIndexLock, 1, 0) != 0)
            {
                AutoCSer.Threading.ThreadYield.YieldOnly();
            }
            switch (getArray[commandIndex].Get(commandCount, out command))
            {
            case 0:
                arrays[freeEndIndex >> bitSize][freeEndIndex & arraySizeAnd].Next = index;
                freeEndIndex = index;
                System.Threading.Interlocked.Exchange(ref freeEndIndexLock, 0);
                return(command);

            case 1:
                System.Threading.Interlocked.Exchange(ref freeEndIndexLock, 0);
                keepCallbackCommand      = command;
                keepCallbackCommandIndex = index;
                return(command);

            default: System.Threading.Interlocked.Exchange(ref freeEndIndexLock, 0); return(null);
            }
        }
예제 #3
0
 internal ClientCommand.Command Pop()
 {
     ClientCommand.Command value = Head.TryFreeBuildQueue();
     if (value != null)
     {
         Head = value;
         return(value);
     }
     return(null);
 }
예제 #4
0
 /// <summary>
 /// 释放客户端命令
 /// </summary>
 /// <param name="command"></param>
 /// <param name="nextIndex"></param>
 /// <returns></returns>
 internal bool Cancel(ClientCommand.Command command, int nextIndex)
 {
     if (Command == command)
     {
         Command = null;
         Next    = nextIndex;
         return(true);
     }
     return(false);
 }
예제 #5
0
 internal ClientCommand.Command CheckTimeout(uint timeoutSeconds, int nextIndex)
 {
     if (Command != null && TimeoutSeconds == timeoutSeconds)
     {
         ClientCommand.Command command = Command;
         Command = null;
         Next    = nextIndex;
         return(command);
     }
     return(null);
 }
예제 #6
0
        /// <summary>
        /// 释放所有命令
        /// </summary>
        /// <param name="head"></param>
        /// <param name="end"></param>
        /// <param name="startIndex"></param>
        /// <returns></returns>
        internal ClientCommand.CommandBase Free(ClientCommand.CommandBase head, ClientCommand.CommandBase end, int startIndex)
        {
            bool isNext = false;

            foreach (CommandLink[] array in arrays)
            {
                if (isNext)
                {
                    if (array == null)
                    {
                        break;
                    }
                    for (startIndex = array.Length; startIndex != 0;)
                    {
                        ClientCommand.Command command = array[--startIndex].Command;
                        if (command != null)
                        {
                            array[startIndex].Command = null;
                            if (head == null)
                            {
                                head = end = command;
                            }
                            else
                            {
                                end.LinkNext = command;
                                end          = command;
                            }
                        }
                    }
                }
                else
                {
                    isNext = true;
                    do
                    {
                        ClientCommand.Command command = array[startIndex].Command;
                        if (command != null)
                        {
                            array[startIndex].Command = null;
                            if (head == null)
                            {
                                head = end = command;
                            }
                            else
                            {
                                end.LinkNext = command;
                                end          = command;
                            }
                        }
                    }while (++startIndex != array.Length);
                }
            }
            return(head);
        }
예제 #7
0
 protected void onReceive(ReturnType type)
 {
     ClientCommand.Command command = CommandPool.GetCommand((int)CommandIndex);
     if (command != null)
     {
         SubArray <byte> data = new SubArray <byte> {
             Start = (int)(byte)type
         };
         command.OnReceive(ref data);
     }
 }
예제 #8
0
 internal int Get(int nextIndex, out ClientCommand.Command command)
 {
     command = Command;
     if (Command.CommandInfo.IsKeepCallback == 0)
     {
         Command = null;
         Next    = nextIndex;
         return(0);
     }
     return(1);
 }
예제 #9
0
 protected void onReceive()
 {
     ClientCommand.Command command = CommandPool.GetCommand((int)CommandIndex);
     if (command != null)
     {
         SubArray <byte> data = new SubArray <byte> {
             Array = ReceiveBuffer.Buffer, Start = ReceiveBuffer.StartIndex + receiveIndex, Length = dataSize
         };
         command.OnReceive(ref data);
     }
 }
예제 #10
0
        internal int Push(ClientCommand.Command command)
        {
            //command.LinkNext = null;
            AutoCSer.Threading.Interlocked.CompareExchangeYieldOnly(ref pushLock);
            int isReadWait = this.isReadWait;

            end.LinkNext    = command;
            end             = command;
            this.isReadWait = 0;
            pushLock        = 0;
            return(isReadWait);
        }
예제 #11
0
        /// <summary>
        /// 取消客户端命令
        /// </summary>
        /// <param name="index"></param>
        /// <param name="command"></param>
        internal void CancelKeep(int index, ClientCommand.Command command)
        {
            int arrayIndex = index >> bitSize, commandIndex = index & arraySizeAnd;

            freeEndIndexLock.Enter();
            if (arrays[arrayIndex][commandIndex].CancelKeep(command, commandCount))
            {
                arrays[freeEndIndex >> bitSize][freeEndIndex & arraySizeAnd].Next = index;
                freeEndIndex = index;
            }
            freeEndIndexLock.Exit();
        }
예제 #12
0
        internal void CancelKeep(ClientCommand.Command command, int commandIndex)
        {
            ClientSocketSender sender = Sender;

            if (sender == null)
            {
                CommandPool.Cancel(commandIndex, command);
            }
            else if (sender.IsSocket && CommandPool[commandIndex] == command)
            {
                CancelKeep(commandIndex);
            }
        }
예제 #13
0
        /// <summary>
        /// 取消客户端命令
        /// </summary>
        /// <param name="index"></param>
        /// <param name="command"></param>
        internal void Cancel(int index, ClientCommand.Command command)
        {
            int arrayIndex = index >> bitSize, commandIndex = index & arraySizeAnd;

            while (System.Threading.Interlocked.CompareExchange(ref freeEndIndexLock, 1, 0) != 0)
            {
                AutoCSer.Threading.ThreadYield.YieldOnly();
            }
            if (arrays[arrayIndex][commandIndex].Cancel(command, commandCount))
            {
                arrays[freeEndIndex >> bitSize][freeEndIndex & arraySizeAnd].Next = index;
                freeEndIndex = index;
            }
            System.Threading.Interlocked.Exchange(ref freeEndIndexLock, 0);
        }
예제 #14
0
 internal int Get(int nextIndex, out ClientCommand.Command command, ref uint timeoutSeconds)
 {
     command = Command;
     if (Command != null)
     {
         if (Command.CommandInfo.IsKeepCallback == 0)
         {
             timeoutSeconds = TimeoutSeconds;
             Command        = null;
             Next           = nextIndex;
             return(0);
         }
         return(1);
     }
     return(2);
 }
예제 #15
0
        /// <summary>
        /// 添加客户端命令
        /// </summary>
        /// <param name="command">客户端命令</param>
        /// <returns>客户端命令索引位置</returns>
        internal int Push(ClientCommand.Command command)
        {
            int index = freeIndex, arrayIndex = freeIndex >> bitSize;

            if (arrayIndex == 0)
            {
                freeIndex = Array[index].Set(command, timeout == null ? 0 : timeout.TryIncrement(command.CommandInfo.TimeoutSeconds));
            }
            else
            {
                if (arrayIndex != pushArrayIndex)
                {
                    pushArray = arrays[pushArrayIndex = arrayIndex];
                }
                freeIndex = pushArray[index & arraySizeAnd].Set(command, timeout == null ? 0 : timeout.TryIncrement(command.CommandInfo.TimeoutSeconds));
            }
            return(freeIndex == commandCount?create(index) : index);
        }
예제 #16
0
        internal int Push(ClientCommand.Command command)
        {
            int index = freeIndex, arrayIndex = freeIndex >> bitSize;

            if (arrayIndex == 0)
            {
                freeIndex = Array[index].Set(command);
            }
            else
            {
                if (arrayIndex != pushArrayIndex)
                {
                    pushArray = arrays[pushArrayIndex = arrayIndex];
                }
                freeIndex = pushArray[index & arraySizeAnd].Set(command);
            }
            return(freeIndex == commandCount?create(index) : index);
        }
예제 #17
0
 internal void OnReceive(ref SubBuffer.PoolBufferFull buffer)
 {
     ClientCommand.Command command = CommandPool.GetCommand((int)CommandIndex);
     if (command == null)
     {
         buffer.Free();
     }
     else
     {
         SubArray <byte> data = new SubArray <byte> {
             Array = buffer.Buffer, Start = buffer.StartIndex, Length = dataSize
         };
         try
         {
             command.OnReceive(ref data);
         }
         finally { buffer.Free(); }
     }
 }
예제 #18
0
 /// <summary>
 /// TCP 调用客户端回调保持
 /// </summary>
 /// <param name="command">客户端命令</param>
 internal KeepCallback(ClientCommand.Command command)
 {
     this.command = command;
 }
예제 #19
0
        /// <summary>
        /// 超时事件
        /// </summary>
        /// <param name="seconds">超时秒计数</param>
        private void onTimeout(uint seconds)
        {
            int startIndex = ClientCommand.KeepCommand.CommandPoolIndex, index = 0;

            ClientCommand.CommandBase head = null, end = null;
            freeEndIndexLock.EnterSleepFlag();
            try
            {
                foreach (CommandLink[] array in arrays)
                {
                    if (index != 0)
                    {
                        if (array == null)
                        {
                            break;
                        }
                        for (startIndex = 0; startIndex != array.Length; ++startIndex, ++index)
                        {
                            ClientCommand.Command command = array[startIndex].CheckTimeout(seconds, commandCount);
                            if (command != null)
                            {
                                arrays[freeEndIndex >> bitSize][freeEndIndex & arraySizeAnd].Next = index;
                                freeEndIndex = index;
                                if (head == null)
                                {
                                    head = end = command;
                                }
                                else
                                {
                                    end.LinkNext = command;
                                    end          = command;
                                }
                            }
                        }
                    }
                    else
                    {
                        index = array.Length;
                        do
                        {
                            ClientCommand.Command command = array[startIndex].CheckTimeout(seconds, commandCount);
                            if (command != null)
                            {
                                arrays[freeEndIndex >> bitSize][freeEndIndex & arraySizeAnd].Next = startIndex;
                                freeEndIndex = startIndex;
                                if (head == null)
                                {
                                    head = end = command;
                                }
                                else
                                {
                                    end.LinkNext = command;
                                    end          = command;
                                }
                            }
                        }while (++startIndex != index);
                    }
                }
            }
            finally
            {
                freeEndIndexLock.ExitSleepFlag();
                if (head != null)
                {
                    ClientCommand.CommandBase.CancelLink(head, ReturnType.Timeout);
                }
                client.CallOnTimeout();
            }
        }
예제 #20
0
 internal void Cancel(int nextIndex)
 {
     Command = null;
     Next    = nextIndex;
 }
예제 #21
0
 internal int Set(ClientCommand.Command command)
 {
     Command = command;
     return(Next);
 }
예제 #22
0
 /// <summary>
 /// 命令队列
 /// </summary>
 /// <param name="command">空闲命令</param>
 internal CommandBuildQueue(ClientCommand.Command command) : base(command)
 {
 }
예제 #23
0
        /// <summary>
        /// 获取客户端命令
        /// </summary>
        /// <param name="index">客户端命令索引位置</param>
        /// <returns>客户端命令</returns>
        internal ClientCommand.Command GetCommand(int index)
        {
            if (keepCallbackCommandIndex == index)
            {
                return(keepCallbackCommand);
            }
            ClientCommand.Command command;
            uint timeoutSeconds = 0;
            int  arrayIndex     = index >> bitSize;

            if (arrayIndex == 0)
            {
                freeEndIndexLock.Enter();
                switch (Array[index].Get(commandCount, out command, ref timeoutSeconds))
                {
                case 0:
                    arrays[freeEndIndex >> bitSize][freeEndIndex & arraySizeAnd].Next = index;
                    freeEndIndex = index;
                    freeEndIndexLock.Exit();
                    if (timeout != null)
                    {
                        timeout.TryDecrement(timeoutSeconds);
                    }
                    return(command);

                case 1:
                    freeEndIndexLock.Exit();
                    keepCallbackCommand      = command;
                    keepCallbackCommandIndex = index;
                    return(command);

                default: freeEndIndexLock.Exit(); return(null);
                }
            }
            if (arrayIndex != getArrayIndex)
            {
                getArray = arrays[getArrayIndex = arrayIndex];
            }
            int commandIndex = index & arraySizeAnd;

            freeEndIndexLock.Enter();
            switch (getArray[commandIndex].Get(commandCount, out command, ref timeoutSeconds))
            {
            case 0:
                arrays[freeEndIndex >> bitSize][freeEndIndex & arraySizeAnd].Next = index;
                freeEndIndex = index;
                freeEndIndexLock.Exit();
                if (timeout != null)
                {
                    timeout.TryDecrement(timeoutSeconds);
                }
                return(command);

            case 1:
                freeEndIndexLock.Exit();
                keepCallbackCommand      = command;
                keepCallbackCommandIndex = index;
                return(command);

            default: freeEndIndexLock.Exit(); return(null);
            }
        }
예제 #24
0
 internal uint Cancel(int nextIndex)
 {
     Command = null;
     Next    = nextIndex;
     return(TimeoutSeconds);
 }
예제 #25
0
 internal int Set(ClientCommand.Command command, uint timeoutSeconds)
 {
     Command        = command;
     TimeoutSeconds = timeoutSeconds;
     return(Next);
 }
예제 #26
0
        /// <summary>
        /// 超时事件
        /// </summary>
        /// <param name="seconds">超时秒计数</param>
        private void onTimeout(uint seconds)
        {
            int startIndex = ClientCommand.KeepCommand.CommandPoolIndex, index = 0;

            ClientCommand.CommandBase head = null, end = null;
            while (System.Threading.Interlocked.CompareExchange(ref freeEndIndexLock, 1, 0) != 0)
            {
                if (isTimeout == 0)
                {
                    AutoCSer.Threading.ThreadYield.YieldOnly();
                }
                else
                {
                    System.Threading.Thread.Sleep(0);
                }
            }
            try
            {
                isTimeout = 1;
                foreach (CommandLink[] array in arrays)
                {
                    if (index != 0)
                    {
                        if (array == null)
                        {
                            break;
                        }
                        for (startIndex = 0; startIndex != array.Length; ++startIndex, ++index)
                        {
                            ClientCommand.Command command = array[startIndex].CheckTimeout(seconds, commandCount);
                            if (command != null)
                            {
                                arrays[freeEndIndex >> bitSize][freeEndIndex & arraySizeAnd].Next = index;
                                freeEndIndex = index;
                                if (head == null)
                                {
                                    head = end = command;
                                }
                                else
                                {
                                    end.LinkNext = command;
                                    end          = command;
                                }
                            }
                        }
                    }
                    else
                    {
                        index = array.Length;
                        do
                        {
                            ClientCommand.Command command = array[startIndex].CheckTimeout(seconds, commandCount);
                            if (command != null)
                            {
                                arrays[freeEndIndex >> bitSize][freeEndIndex & arraySizeAnd].Next = startIndex;
                                freeEndIndex = startIndex;
                                if (head == null)
                                {
                                    head = end = command;
                                }
                                else
                                {
                                    end.LinkNext = command;
                                    end          = command;
                                }
                            }
                        }while (++startIndex != index);
                    }
                }
            }
            finally
            {
                isTimeout = 0;
                System.Threading.Interlocked.Exchange(ref freeEndIndexLock, 0);
                if (head != null)
                {
                    ClientCommand.CommandBase.CancelLink(head, ReturnType.Timeout);
                }
                client.CallOnTimeout();
            }
        }
예제 #27
0
        /// <summary>
        /// 释放所有命令
        /// </summary>
        /// <param name="head"></param>
        /// <param name="end"></param>
        /// <param name="startIndex"></param>
        /// <returns></returns>
        internal ClientCommand.CommandBase Free(ClientCommand.CommandBase head, ClientCommand.CommandBase end, int startIndex)
        {
            DisposeTimeout();
            bool isNext = false;

            while (System.Threading.Interlocked.CompareExchange(ref freeEndIndexLock, 1, 0) != 0)
            {
                if (isTimeout == 0)
                {
                    AutoCSer.Threading.ThreadYield.YieldOnly();
                }
                else
                {
                    System.Threading.Thread.Sleep(0);
                }
            }
            try
            {
                foreach (CommandLink[] array in arrays)
                {
                    if (isNext)
                    {
                        if (array == null)
                        {
                            break;
                        }
                        for (startIndex = array.Length; startIndex != 0;)
                        {
                            ClientCommand.Command command = array[--startIndex].Command;
                            if (command != null)
                            {
                                array[startIndex].Command = null;
                                if (head == null)
                                {
                                    head = end = command;
                                }
                                else
                                {
                                    end.LinkNext = command;
                                    end          = command;
                                }
                            }
                        }
                    }
                    else
                    {
                        isNext = true;
                        do
                        {
                            ClientCommand.Command command = array[startIndex].Command;
                            if (command != null)
                            {
                                array[startIndex].Command = null;
                                if (head == null)
                                {
                                    head = end = command;
                                }
                                else
                                {
                                    end.LinkNext = command;
                                    end          = command;
                                }
                            }
                        }while (++startIndex != array.Length);
                    }
                }
            }
            finally { System.Threading.Interlocked.Exchange(ref freeEndIndexLock, 0); }
            return(head);
        }