Example #1
0
        // Unlock a resource: find the entry and call unregister lock
        private void Unlock(TP.Transaction context, TP.Lockable resource, LockMode mode)
        {
            ResourceEntry lockTarget;

            // Get exclusive access to the lock table
            lock (this.ResourceTable)
            {
                this.ResourceTable.TryGetValue(resource, out lockTarget);

                // Check if the resource wasn't locked, and if so, then return
                if (lockTarget == null)
                {
                    return;
                }
            }

            // Get exclusive access to the resource
            lock (lockTarget)
            {
                lockTarget.Unregister(context, mode);
            }
        }
Example #2
0
 // A shortcut to unlock a write lock
 public void UnlockWrite(TP.Transaction context, TP.Lockable resource)
 {
     Unlock(context, resource, LockMode.Write);
 }
Example #3
0
 // A shortcut to unlock a read lock
 public void UnlockRead(TP.Transaction context, TP.Lockable resource)
 {
     Unlock(context, resource, LockMode.Read);
 }
Example #4
0
 // Get a write lock for the resource
 public void LockForWrite(TP.Transaction context, TP.Lockable resource)
 {
     Lock(context, resource, MyLM.LockMode.Write);
 }
Example #5
0
 // Get a read lock for the resource
 public void LockForRead(TP.Transaction context, TP.Lockable resource)
 {
     Lock(context, resource, MyLM.LockMode.Read);
 }
Example #6
0
        /* Lock passed in resource _resource_ in mode _mode_
         * This method needs additional code to implement lock conversion.
         * It does deadlock detection by timeout */
        private void Lock(TP.Transaction context, TP.Lockable resource, LockMode mode)
        {
            ResourceEntry lockTarget;

            /* Get exclusive access to the lock table
             * This avoids race conditions, such as two conflicting locks being granted to concurrent threads (i.e., transactions),
             * or two physical resources created for one logical resource on behalf of two threads. */

            lock (this.ResourceTable)
            {
                // Pick the needed resource from ResourceTable
                this.ResourceTable.TryGetValue(resource, out lockTarget);

                // Create a ResourceEntry for resource, if there is none
                if (lockTarget == null)
                {
                    lockTarget = new ResourceEntry();
                    this.ResourceTable[resource] = lockTarget;
                }
            }

            for (int c = 0; ; c++)
            {
                /* If someone else holds a lock
                 * (the loop already executed once and failed to set the lock)
                 * wait for 5 seconds for the lock to be released and
                 * if it doesn't happen, timeout for deadlock,
                 * else try again to set the lock */
                if (c > 0)
                {
                    if (!lockTarget.UnlockEvent.WaitOne(System.TimeSpan.FromMilliseconds((double)deadlockTimeout), false))
                    {
                        throw new DeadLockDetected(string.Format("Resource {0} timed out", resource));
                    }
                }

                if (c > 0)
                {
                    System.Console.WriteLine(string.Format("Attempt {0} in resource {1}", c, resource));
                }

                // Get exclusive access to the resource
                lock (lockTarget)
                {
                    // Set the lock, if you can
                    if (lockTarget.Compatible(mode))
                    {
                        lockTarget.Register(context, mode);
                        return;
                    }
                    // If the request is read, see if the transaction alreday has a write lock on the resource
                    else if (mode == LockMode.Read && lockTarget.DownGradedLockRequest(context, mode))
                    {
                        // ‘context’ has a write lock on lockTarget and requested a read lock so no action is required.                        //
                        return;
                    }
                    // If the request is write and the transaction already has a read lock on the resource, try
                    // to upgrade the read lock to a write lock if no other transactions has a lock on this resource
                    else if (mode == LockMode.Write && lockTarget.UpgradeLockRequest(context, mode))
                    {
                        return;
                    }
                }
            }

            // Debug
            throw new System.Exception("Internal Error");
        }