File: FaultCallbackWrapper.cs

package info (click to toggle)
mono 6.8.0.105%2Bdfsg-3.3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,284,512 kB
  • sloc: cs: 11,172,132; xml: 2,850,069; ansic: 671,653; cpp: 122,091; perl: 59,366; javascript: 30,841; asm: 22,168; makefile: 20,093; sh: 15,020; python: 4,827; pascal: 925; sql: 859; sed: 16; php: 1
file content (153 lines) | stat: -rw-r--r-- 6,988 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

namespace System.Activities.Runtime
{
    using System;
    using System.Runtime;
    using System.Runtime.Serialization;
    using System.Security;

    [DataContract]
    class FaultCallbackWrapper : CallbackWrapper
    {
        static readonly Type faultCallbackType = typeof(FaultCallback);
        static readonly Type[] faultCallbackParameters = new Type[] { typeof(NativeActivityFaultContext), typeof(Exception), typeof(ActivityInstance) };

        public FaultCallbackWrapper(FaultCallback callback, ActivityInstance owningInstance)
            : base(callback, owningInstance)
        {
        }

        [Fx.Tag.SecurityNote(Critical = "Because we are calling EnsureCallback",
            Safe = "Safe because the method needs to be part of an Activity and we are casting to the callback type and it has a very specific signature. The author of the callback is buying into being invoked from PT.")]
        [SecuritySafeCritical]
        public void Invoke(NativeActivityFaultContext faultContext, Exception propagatedException, ActivityInstance propagatedFrom)
        {
            EnsureCallback(faultCallbackType, faultCallbackParameters);
            FaultCallback faultCallback = (FaultCallback)this.Callback;
            faultCallback(faultContext, propagatedException, propagatedFrom);
        }

        public WorkItem CreateWorkItem(Exception propagatedException, ActivityInstance propagatedFrom, ActivityInstanceReference originalExceptionSource)
        {
            return new FaultWorkItem(this, propagatedException, propagatedFrom, originalExceptionSource);
        }

        [DataContract]
        internal class FaultWorkItem : ActivityExecutionWorkItem
        {
            FaultCallbackWrapper callbackWrapper;
            Exception propagatedException;
            ActivityInstance propagatedFrom;
            ActivityInstanceReference originalExceptionSource;

            public FaultWorkItem(FaultCallbackWrapper callbackWrapper, Exception propagatedException, ActivityInstance propagatedFrom, ActivityInstanceReference originalExceptionSource)
                : base(callbackWrapper.ActivityInstance)
            {
                this.callbackWrapper = callbackWrapper;
                this.propagatedException = propagatedException;
                this.propagatedFrom = propagatedFrom;
                this.originalExceptionSource = originalExceptionSource;
            }

            public override ActivityInstance OriginalExceptionSource
            {
                get
                {
                    return this.originalExceptionSource.ActivityInstance;
                }
            }

            [DataMember(Name = "callbackWrapper")]
            internal FaultCallbackWrapper SerializedCallbackWrapper
            {
                get { return this.callbackWrapper; }
                set { this.callbackWrapper = value; }
            }

            [DataMember(Name = "propagatedException")]
            internal Exception SerializedPropagatedException
            {
                get { return this.propagatedException; }
                set { this.propagatedException = value; }
            }

            [DataMember(Name = "propagatedFrom")]
            internal ActivityInstance SerializedPropagatedFrom
            {
                get { return this.propagatedFrom; }
                set { this.propagatedFrom = value; }
            }

            [DataMember(Name = "originalExceptionSource")]
            internal ActivityInstanceReference SerializedOriginalExceptionSource
            {
                get { return this.originalExceptionSource; }
                set { this.originalExceptionSource = value; }
            }

            public override void TraceCompleted()
            {
                if (TD.CompleteFaultWorkItemIsEnabled())
                {
                    TD.CompleteFaultWorkItem(this.ActivityInstance.Activity.GetType().ToString(), this.ActivityInstance.Activity.DisplayName, this.ActivityInstance.Id, this.originalExceptionSource.ActivityInstance.Activity.GetType().ToString(), this.originalExceptionSource.ActivityInstance.Activity.DisplayName, this.originalExceptionSource.ActivityInstance.Id, this.propagatedException);
                }
            }

            public override void TraceScheduled()
            {
                if (TD.ScheduleFaultWorkItemIsEnabled())
                {
                    TD.ScheduleFaultWorkItem(this.ActivityInstance.Activity.GetType().ToString(), this.ActivityInstance.Activity.DisplayName, this.ActivityInstance.Id, this.originalExceptionSource.ActivityInstance.Activity.GetType().ToString(), this.originalExceptionSource.ActivityInstance.Activity.DisplayName, this.originalExceptionSource.ActivityInstance.Id, this.propagatedException);
                }
            }

            public override void TraceStarting()
            {
                if (TD.StartFaultWorkItemIsEnabled())
                {
                    TD.StartFaultWorkItem(this.ActivityInstance.Activity.GetType().ToString(), this.ActivityInstance.Activity.DisplayName, this.ActivityInstance.Id, this.originalExceptionSource.ActivityInstance.Activity.GetType().ToString(), this.originalExceptionSource.ActivityInstance.Activity.DisplayName, this.originalExceptionSource.ActivityInstance.Id, this.propagatedException);
                }
            }

            public override bool Execute(ActivityExecutor executor, BookmarkManager bookmarkManager)
            {
                NativeActivityFaultContext faultContext = null;

                try
                {
                    faultContext = new NativeActivityFaultContext(this.ActivityInstance, executor, bookmarkManager, this.propagatedException, this.originalExceptionSource);
                    this.callbackWrapper.Invoke(faultContext, this.propagatedException, this.propagatedFrom);

                    if (!faultContext.IsFaultHandled)
                    {
                        SetExceptionToPropagateWithoutAbort(this.propagatedException);
                    }
                }
                catch (Exception e)
                {
                    if (Fx.IsFatal(e))
                    {
                        throw;
                    }

                    this.ExceptionToPropagate = e;
                }
                finally
                {
                    if (faultContext != null)
                    {
                        faultContext.Dispose();
                    }

                    // Tell the executor to decrement its no persist count persistence of exceptions is disabled.
                    executor.ExitNoPersistForExceptionPropagation();
                }

                return true;
            }
        }
    }
}