Example #1
0
        public static void EmitLock(this ILProcessor il, Action loadSyncRoot, Action block)
        {
            var lockTaken = new VariableDefinition(/*"$lockTaken",*/ il.Body.Method.Module.ImportReference(typeof(bool)));

            il.Body.Variables.Add(lockTaken);
            var syncRoot = new VariableDefinition(/*"$root",*/ il.Body.Method.Module.ImportReference(typeof(object)));

            il.Body.Variables.Add(syncRoot);
            il.Emit(OpCodes.Ldc_I4_0);
            il.Emit(OpCodes.Stloc, lockTaken);
            il.EmitTryFinally(() =>
            {
                loadSyncRoot();
                il.Emit(OpCodes.Dup);
                il.Emit(OpCodes.Stloc, syncRoot);
                il.Emit(OpCodes.Ldloca, lockTaken);
                il.Emit(OpCodes.Call, il.Body.Method.Module.ImportReference(_monitorEnter));
                block();
            }, () =>
            {
                il.Emit(OpCodes.Ldloc, lockTaken);
                using (il.BranchIfFalse())
                {
                    il.Emit(OpCodes.Ldloc, syncRoot);
                    il.Emit(OpCodes.Call, il.Body.Method.Module.ImportReference(_monitorExit));
                }
            });
        }