public bool Timeout(MalockTaskInfo info) { MalockMessage message = this.NewMessage(info.Key, info.Identity, MalockMessage.COMMON_COMMAND_TIMEOUT, info.Sequence, info.Timeout); MalockMessage.TrySendMessage(info.Socket, message); return(true); }
public void AckPipelineExit(MalockTaskInfo info) // anti-deadlock { string key = this.GetAckPipelineKey(info); lock (this.ackPipelineCounter) { bool entering = this.malockTable.IsEnter(info.Key, info.Identity); int count = 0; if (!this.ackPipelineCounter.TryGetValue(key, out count)) { if (entering) { this.ackPipelineCounter.Add(key, ++count); } } else if (!entering) { count = 0; // reset counter this.ackPipelineCounter[key] = 0; } else { this.ackPipelineCounter[key] = ++count; } if (count > Malock.AckPipelineDeadlockCount) { this.ackPipelineCounter[key] = 0; this.Exit(info); } } }
public unsafe bool GetAllInfo(MalockTaskInfo info) { using (MemoryStream stream = new MemoryStream()) { BinaryWriter bw = new BinaryWriter(stream); bw.Write(0); int count = 0; lock (this.malockTable) { foreach (var locker in this.malockTable.GetAllLocker()) { lock (locker) { HandleInfo handleInfo = new HandleInfo( locker.Key, locker.Identity, locker.Available); handleInfo.Serialize(stream); } count++; } } byte[] buffer = stream.GetBuffer(); fixed(byte *pinned = buffer) { *(int *)pinned = count; } MalockMessage message = this.NewMessage(info.Key, info.Identity, MalockNodeMessage.CLIENT_COMMAND_GETALLINFO, info.Sequence, -1); return(MalockMessage.TrySendMessage(info.Socket, message, buffer, 0, Convert.ToInt32(stream.Position))); } }
private void Handle(MalockTaskType type, MalockTaskTable tables) { foreach (var kv in tables) { LinkedList <MalockTaskInfo> tasks = kv.Value; MalockTaskInfo info = null; LinkedListNode <MalockTaskInfo> node = null; lock (tasks) { node = tasks.First; if (node == null) { continue; } info = node.Value; } bool success = false; Stopwatch sw = info.Stopwatch; if (sw != null && info.Timeout != -1 && sw.ElapsedMilliseconds > info.Timeout) { success = this.engine.Timeout(info); } else { switch (type) { case MalockTaskType.kEnter: success = this.engine.Enter(info); break; case MalockTaskType.kExit: success = this.engine.Exit(info); break; case MalockTaskType.kAbort: success = this.engine.Abort(info); break; case MalockTaskType.kGetAllInfo: success = this.engine.GetAllInfo(info); break; } } if (success) { lock (tasks) { if (node.List != null) { tasks.Remove(node); } } } } }
public void AckPipelineEnter(MalockTaskInfo info) { string key = this.GetAckPipelineKey(info); lock (this.ackPipelineCounter) { int count = 0; if (this.ackPipelineCounter.TryGetValue(key, out count)) { this.ackPipelineCounter[key] = 0; } } }
public bool Abort(MalockTaskInfo info) { if (string.IsNullOrEmpty(info.Identity)) { return(false); } this.malockTaskPoll.Remove(info.Identity); do { string[] keys; this.malockTable.FreeKeyCollection(info.Identity, out keys); this.AckPipelineEnter(info.Identity, keys); } while (false); MalockMessage message = this.NewMessage(info.Key, info.Identity, MalockNodeMessage.SERVER_COMMAND_SYN_FREE, info.Sequence, -1); MalockMessage.TrySendMessage(this.malockStandbyClient, message); return(true); }
public bool Exit(MalockTaskInfo info) { byte errno = MalockNodeMessage.CLIENT_COMMAND_LOCK_EXIT; if (!this.malockTable.Exit(info.Key, info.Identity)) { errno = MalockMessage.COMMON_COMMAND_ERROR; } using (Stream message = this.NewMessage(info.Key, info.Identity, errno, info.Sequence, info.Timeout).Serialize()) { if (info.Socket != null) { MalockMessage.TrySendMessage(info.Socket, message); } MalockMessage.TrySendMessage(malockStandbyClient, message); } this.AckPipelineEnter(info); return(true); }
public void Add(MalockTaskInfo info) { LinkedList <MalockTaskInfo> tasks; string identity = info.Identity; lock (this.tables) { MalockTaskTable tables = this.GetTable(info.Type); if (!tables.TryGetValue(identity, out tasks)) { tasks = new LinkedList <MalockTaskInfo>(); tables.TryAdd(identity, tasks); } lock (tasks) { tasks.AddLast(info); } } }
public bool Enter(MalockTaskInfo info) { if (!this.malockTable.Enter(info.Key, info.Identity)) { return(false); } using (Stream message = this.NewMessage(info.Key, info.Identity, MalockNodeMessage.CLIENT_COMMAND_LOCK_ENTER, info.Sequence, info.Timeout).Serialize()) { if (MalockMessage.TrySendMessage(info.Socket, message)) { MalockMessage.TrySendMessage(this.malockStandbyClient, message); return(true); } else { this.malockTable.Exit(info.Key, info.Identity); this.AckPipelineEnter(info); } } return(false); }
private string GetAckPipelineKey(MalockTaskInfo info) { return(this.GetAckPipelineKey(info.Identity, info.Key)); }
private void ProcessClient(MalockSocket socket, MalockNodeMessage message) { if (message.Command == MalockNodeMessage.CLIENT_COMMAND_LOCK_ENTER || message.Command == MalockNodeMessage.CLIENT_COMMAND_LOCK_EXIT || message.Command == MalockNodeMessage.CLIENT_COMMAND_GETALLINFO || message.Command == MalockNodeMessage.CLIENT_COMMAND_LOCK_ACKPIPELINEEXIT || message.Command == MalockNodeMessage.CLIENT_COMMAND_LOCK_ACKPIPELINEENTER) { MalockTaskInfo info = new MalockTaskInfo(); switch (message.Command) { case MalockNodeMessage.CLIENT_COMMAND_LOCK_ENTER: info.Type = MalockTaskType.kEnter; break; case MalockNodeMessage.CLIENT_COMMAND_LOCK_EXIT: info.Type = MalockTaskType.kExit; break; case MalockNodeMessage.CLIENT_COMMAND_GETALLINFO: info.Type = MalockTaskType.kGetAllInfo; break; case MalockNodeMessage.CLIENT_COMMAND_LOCK_ACKPIPELINEEXIT: info.Type = MalockTaskType.kAckPipelineExit; break; case MalockNodeMessage.CLIENT_COMMAND_LOCK_ACKPIPELINEENTER: info.Type = MalockTaskType.kAckPipelineEnter; break; } info.Sequence = message.Sequence; info.Socket = socket; info.Key = message.Key; info.Identity = socket.Identity; info.Timeout = message.Timeout; do { Stopwatch sw = new Stopwatch(); info.Stopwatch = sw; sw.Start(); } while (false); if (message.Command == MalockNodeMessage.CLIENT_COMMAND_LOCK_EXIT) { this.malockEngine.Exit(info); } else if (message.Command == MalockNodeMessage.CLIENT_COMMAND_LOCK_ENTER) { if (this.malockEngine.Enter(info)) { this.malockEngine.AckPipelineEnter(info); } else { this.malockEngine.GetPoll().Add(info); } } else if (message.Command == MalockNodeMessage.CLIENT_COMMAND_LOCK_ACKPIPELINEEXIT) { this.malockEngine.AckPipelineExit(info); // anti-deadlock } else if (message.Command == MalockNodeMessage.CLIENT_COMMAND_LOCK_ACKPIPELINEENTER) { this.malockEngine.AckPipelineEnter(info); } else if (message.Command == MalockNodeMessage.CLIENT_COMMAND_GETALLINFO) { this.malockEngine.GetAllInfo(info); } } }