Ejemplo n.º 1
0
        internal static ForwarderDelegate GetForwarder(MethodInfo method)
        {
            lock (forwarders) {
                ForwarderDelegate d;
                if (forwarders.TryGetValue(method, out d))
                {
                    return(d);
                }
            }

            if (method.DeclaringType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Length != 0)
            {
                throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
            }
            ParameterInfo[] parameters = method.GetParameters();

            Debug.Assert(getTarget != null);

            DynamicMethod dm = new DynamicMethod("SmartWeakEvent", typeof(Boolean), forwarderParameters, method.DeclaringType);

            ILGenerator il = dm.GetILGenerator();

            if (!method.IsStatic)
            {
                il.Emit(OpCodes.Ldarg_0);
                il.EmitCall(OpCodes.Callvirt, getTarget, null);
                il.Emit(OpCodes.Dup);
                Label label = il.DefineLabel();
                il.Emit(OpCodes.Brtrue, label);
                il.Emit(OpCodes.Pop);
                il.Emit(OpCodes.Ldc_I4_1);
                il.Emit(OpCodes.Ret);
                il.MarkLabel(label);
                // The castclass here is required for the generated code to be verifiable.
                // We can leave it out because we know this cast will always succeed
                // (the instance/method pair was taken from a delegate).
                // Unverifiable code is fine because private reflection is only allowed under FullTrust
                // anyways.
                //il.Emit(OpCodes.Castclass, method.DeclaringType);
            }
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldarg_2);
            // This castclass here is required to prevent creating a hole in the .NET type system.
            // See Program.TypeSafetyProblem in the 'SmartWeakEventBenchmark' to see the effect when
            // this cast is not used.
            // You can remove this cast if you trust add SmartWeakEvent.Raise callers to do
            // the right thing, but the small performance increase (about 5%) usually isn't worth the risk.
            il.Emit(OpCodes.Castclass, parameters[1].ParameterType);

            il.EmitCall(OpCodes.Call, method, null);
            il.Emit(OpCodes.Ldc_I4_0);
            il.Emit(OpCodes.Ret);

            ForwarderDelegate fd = (ForwarderDelegate)dm.CreateDelegate(typeof(ForwarderDelegate));

            lock (forwarders) {
                forwarders[method] = fd;
            }
            return(fd);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Dynamically emits a delegate for event forwarding
        /// </summary>
        /// <param name="method">The methodInfo to use for forward</param>
        /// <returns>Delegate for event forwarding</returns>
        internal static ForwarderDelegate GetForwarder(MethodInfo method)
        {
            lock (forwarders)
            {
                ForwarderDelegate d;
                if (forwarders.TryGetValue(method, out d))
                {
                    return(d);
                }
            }

            if ((method == null) || (method.DeclaringType == null))
            {
                throw new ArgumentNullException(nameof(method));
            }

            if (method.DeclaringType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Length != 0)
            {
                throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
            }

            Debug.Assert(getTarget != null);

            DynamicMethod dm = new DynamicMethod(
                "WeakEvent", typeof(bool), forwarderParameters, method.DeclaringType);

            ILGenerator il = dm.GetILGenerator();

            if (!method.IsStatic)
            {
                il.Emit(OpCodes.Ldarg_0);
                il.EmitCall(OpCodes.Callvirt, getTarget, null);
                il.Emit(OpCodes.Dup);
                Label label = il.DefineLabel();
                il.Emit(OpCodes.Brtrue, label);
                il.Emit(OpCodes.Pop);
                il.Emit(OpCodes.Ldc_I4_1);
                il.Emit(OpCodes.Ret);
                il.MarkLabel(label);
            }
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldarg_2);
            il.EmitCall(OpCodes.Call, method, null);
            il.Emit(OpCodes.Ldc_I4_0);
            il.Emit(OpCodes.Ret);

            ForwarderDelegate fd = (ForwarderDelegate)dm.CreateDelegate(typeof(ForwarderDelegate));

            lock (forwarders)
            {
                forwarders[method] = fd;
            }

            return(fd);
        }
Ejemplo n.º 3
0
        public DequeueSynchronizer(int workers, IQueueHandler queueHandler, ForwarderDelegate forwarder)
        {
            TotalWorkers = workers;
            _runningWorkers = workers;
            _workers = new Thread[workers];
            _forwarder = forwarder;

            _suspendWorkersEvent = new EventWaitHandle(true, EventResetMode.ManualReset);
            _runningWorkerEvents = new EventWaitHandle[workers];
            _suspendedWorkerEvents = new EventWaitHandle[workers];
            _terminatingWorkerEvents = new EventWaitHandle[workers];

            for (int count = 0; count < workers; ++count)
            {
                _runningWorkerEvents[count] = new EventWaitHandle(false, EventResetMode.ManualReset);
                _suspendedWorkerEvents[count] = new EventWaitHandle(false, EventResetMode.ManualReset);
                _terminatingWorkerEvents[count] = new EventWaitHandle(false, EventResetMode.ManualReset);
                _workers[count] = new Thread(DequeueWorker);
                _workers[count].Start(new WorkerParams(count, queueHandler.GetDequeuer()));
            }

            SuspendWorkers();
        }