Beispiel #1
0
        /// <summary>
        /// Tries to lock the correlated todo instance with the specified scheduled date, true if locked, false, otherwise.
        /// Takes lock IF not enqueue, false otherwise
        /// </summary>
        private bool tryLockCorrelatedProcessing(string key, DateTime sd)
        {
            if (key == null)
            {
                key = string.Empty;
            }

            lock (m_CorrelationLocker)
            {
                _lck lck;
                if (!m_CorrelationLocker.TryGetValue(key, out lck))
                {
                    lck = new _lck {
                        Date = sd, IsEnqueue = 0, IsProc = 1
                    };
                    m_CorrelationLocker.Add(key, lck);
                    return(true);
                }

                if (lck.IsEnqueue == 0)
                {
                    lck.IsProc++;
                    if (sd > lck.Date)
                    {
                        lck.Date = sd;
                    }
                    return(true);
                }

                return(false);//lock is enqueue type
            }
        }
Beispiel #2
0
/*
 * Locking works as follows:
 * ---------------------------
 * All locking is done per CorrelationKey (different CorrelationKey do not inter-lock at all)
 * Within the same key:
 *
 *   Any existing Enqueue lock blocks another Enqueue until existing is released
 *   Any existing Enqueue lock returns FALSE for another Process until all Enqueue released
 *
 *   Any existing Processing lock yields next date to Enqueue (+1 sec)
 *   Any Exisiting Processing lock shifts next Date if another Processing lock is further advanced in time
 *
 *
 *   Enqueue lock is reentrant for the same thread.
 *   Processing lock is reentrant regardless of thread ownership
 *
 */



        /// <summary>
        /// Returns the point in time AFTER which the enqueue operation may fetch correlated todos
        /// </summary>
        private DateTime lockCorrelatedEnqueue(string key, DateTime sd)
        {
            if (key == null)
            {
                key = string.Empty;
            }

            var ct = Thread.CurrentThread;

            uint spinCount = 0;

            while (true)
            {
                lock (m_CorrelationLocker)
                {
                    _lck lck;
                    if (!m_CorrelationLocker.TryGetValue(key, out lck))
                    {
                        lck = new _lck {
                            TEnqueue = ct, Date = sd, IsEnqueue = 1, IsProc = 0
                        };
                        m_CorrelationLocker.Add(key, lck);
                        return(sd);
                    }

                    if (lck.IsEnqueue == 0)
                    {
                        lck.IsEnqueue = 1;
                        lck.TEnqueue  = ct;
                        return(lck.Date.AddSeconds(1));
                    }

                    if (lck.TEnqueue == ct)//if already acquired by this thread
                    {
                        lck.IsEnqueue++;
                        if (sd < lck.Date)
                        {
                            lck.Date = sd;
                        }
                        return(lck.Date);
                    }
                }
                if (spinCount < 100)
                {
                    Thread.SpinWait(500);
                }
                else
                {
                    Thread.Yield();
                }

                unchecked { spinCount++; }
            }
        }