Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
                }
            }
        }
Esempio n. 3
0
        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)));
            }
        }
Esempio n. 4
0
        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);
                        }
                    }
                }
            }
        }
Esempio n. 5
0
        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;
                }
            }
        }
Esempio n. 6
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);
        }
Esempio n. 7
0
        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);
        }
Esempio n. 8
0
        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);
                }
            }
        }
Esempio n. 9
0
 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);
 }
Esempio n. 10
0
 private string GetAckPipelineKey(MalockTaskInfo info)
 {
     return(this.GetAckPipelineKey(info.Identity, info.Key));
 }
Esempio n. 11
0
        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);
                }
            }
        }