/// <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); }
/// <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); } }
internal ClientCommand.Command Pop() { ClientCommand.Command value = Head.TryFreeBuildQueue(); if (value != null) { Head = value; return(value); } return(null); }
/// <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); }
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); }
/// <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); }
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); } }
internal int Get(int nextIndex, out ClientCommand.Command command) { command = Command; if (Command.CommandInfo.IsKeepCallback == 0) { Command = null; Next = nextIndex; return(0); } return(1); }
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); } }
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); }
/// <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(); }
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); } }
/// <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); }
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); }
/// <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); }
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); }
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(); } } }
/// <summary> /// TCP 调用客户端回调保持 /// </summary> /// <param name="command">客户端命令</param> internal KeepCallback(ClientCommand.Command command) { this.command = command; }
/// <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(); } }
internal void Cancel(int nextIndex) { Command = null; Next = nextIndex; }
internal int Set(ClientCommand.Command command) { Command = command; return(Next); }
/// <summary> /// 命令队列 /// </summary> /// <param name="command">空闲命令</param> internal CommandBuildQueue(ClientCommand.Command command) : base(command) { }
/// <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); } }
internal uint Cancel(int nextIndex) { Command = null; Next = nextIndex; return(TimeoutSeconds); }
internal int Set(ClientCommand.Command command, uint timeoutSeconds) { Command = command; TimeoutSeconds = timeoutSeconds; return(Next); }
/// <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(); } }
/// <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); }