Ejemplo n.º 1
0
 /// <summary>
 /// Unlock all the specified keys.
 /// </summary>
 /// <param name="cache">
 /// The <see cref="IConcurrentCache"/> to use.
 /// </param>
 /// <param name="keys">
 /// A collection of keys to unlock.
 /// </param>
 public static void UnlockAll(IConcurrentCache cache, ICollection keys)
 {
     foreach (var key in keys)
     {
         cache.Unlock(key);
     }
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Attempt to lock all the specified keys within a specified period
        /// of time.
        /// </summary>
        /// <param name="cache">
        /// The <see cref="IConcurrentCache"/> to use.
        /// </param>
        /// <param name="keys">
        /// A collection of keys to lock.
        /// </param>
        /// <param name="waitMillis">
        /// The number of milliseconds to continue trying to obtain locks;
        /// pass zero to return immediately; pass -1 to block the calling
        /// thread until the lock could be obtained.
        /// </param>
        /// <returns>
        /// An <b>IList</b> containing all the locked keys in the order
        /// opposite to the locking order (LIFO); <c>null</c> if timeout has
        /// occurred.
        /// </returns>
        public static IList LockAll(IConcurrentCache cache, ICollection keys,
                                    int waitMillis)
        {
            // remove the duplicates
            HashSet setKeys = keys is HashSet ? (HashSet)keys : new HashSet(keys);

            // copy the keys into a list to fully control the iteration order
            var  listKeys   = new ArrayList(setKeys);
            var  listLocked = new ArrayList();
            int  keysCount  = listKeys.Count;
            bool isSuccess  = true;

            do
            {
                int waitNextMillis = waitMillis; // allow blocking wait for the very first key
                for (int i = 0; i < keysCount; i++)
                {
                    var key = listKeys[i];

                    isSuccess = cache.Lock(key, waitNextMillis);
                    if (isSuccess)
                    {
                        // add the last locked item into the front of the locked
                        // list so it behaves as a stack (FILO strategy)
                        listLocked.Insert(0, key);

                        // to prevent a deadlock don't wait afterwards
                        waitNextMillis = 0;
                    }
                    else
                    {
                        if (i == 0)
                        {
                            // the very first key cannot be locked -- timeout
                            return(null);
                        }

                        // unlock all we hold and try again
                        foreach (var o in listLocked)
                        {
                            cache.Unlock(o);
                        }
                        listLocked.Clear();

                        // move the "offending" key to the top of the list
                        // so next iteration we will attempt to lock it first
                        listKeys.RemoveAt(i);
                        listKeys.Insert(0, key);
                    }
                }
            }while (!isSuccess);

            return(listLocked);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Invoke the passed <see cref="IEntryProcessor"/> against the
        /// specified <see cref="IInvocableCacheEntry"/>.
        /// </summary>
        /// <remarks>
        /// The invocation is made thread safe by locking the corresponding key
        /// on the cache.
        /// </remarks>
        /// <param name="cache">
        /// The <see cref="IConcurrentCache"/> that the
        /// <b>IEntryProcessor</b> works against.
        /// </param>
        /// <param name="entry">
        /// The <b>IInvocableCacheEntry</b> to process; it is not required to
        /// exist within the cache.
        /// </param>
        /// <param name="agent">
        /// The <b>IEntryProcessor</b> to use to process the specified key.
        /// </param>
        /// <returns>
        /// The result of the invocation as returned from the
        /// <b>IEntryProcessor</b>.
        /// </returns>
        public static object InvokeLocked(IConcurrentCache cache,
                                          IInvocableCacheEntry entry, IEntryProcessor agent)
        {
            var key = entry.Key;

            cache.Lock(key, -1);
            try
            {
                return(agent.Process(entry));
            }
            finally
            {
                cache.Unlock(key);
            }
        }