File: ProgramPublisher.cs

package info (click to toggle)
mono 6.14.1%2Bds2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,282,732 kB
  • sloc: cs: 11,182,461; xml: 2,850,281; ansic: 699,123; cpp: 122,919; perl: 58,604; javascript: 30,841; asm: 21,845; makefile: 19,602; sh: 10,973; python: 4,772; pascal: 925; sql: 859; sed: 16; php: 1
file content (140 lines) | stat: -rw-r--r-- 4,638 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
// Copyright (c) Microsoft Corp., 2004. All rights reserved.
#region Using directives

using System;
using System.Threading;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Diagnostics;

#endregion

namespace System.Workflow.Runtime.DebugEngine
{
    [ComImport, Guid(Guids.CLSID_WDEProgramPublisher)]
    internal class WDEProgramPublisher
    {
    }

    internal sealed class ProgramPublisher
    {
        #region Data members

        private bool isPublished = false;
        IWDEProgramPublisher publisher;
        private DebugController controller;
        GCHandle gchWdeProgramNode; // This is used to pin the wdeProgramNodeSingleton (VS Debugger is using address to calculate cookies)
        private IWDEProgramNode wdeProgramNodeSingleton;

        #endregion

        #region Methods

        public ProgramPublisher()
        {
            this.publisher = null;
        }

        public bool Publish(DebugController controller)
        {
            Debug.WriteLine("WDE: ProgramPublisher.Publish()");

            // In order to guarantee that the Program Nodes are always in the MTA, publish on a separate thread.
            if (isPublished)
                return false;

            try
            {
                this.controller = controller;
                Thread publisherThread = new Thread(PublisherThreadFunc);
                publisherThread.SetApartmentState(ApartmentState.MTA);
                publisherThread.IsBackground = true;
                publisherThread.Start();
                publisherThread.Join();
            }
            catch (Exception e)
            {
                // Eat up exceptions if the debugger is not installed.
                Debug.WriteLine("WDE: ProgramPublisher.Publish() exception: " + e.ToString());
            }

            return this.isPublished;
        }

        private void PublisherThreadFunc()
        {
            try
            {
                this.publisher = new WDEProgramPublisher() as IWDEProgramPublisher;
                this.wdeProgramNodeSingleton = new ProgramNode(this.controller);
                this.gchWdeProgramNode = GCHandle.Alloc(this.wdeProgramNodeSingleton);

                this.publisher.Publish(this.wdeProgramNodeSingleton);
                this.isPublished = true;
            }
            catch (Exception e)
            {
                // Ignore any exceptions that are caused by WDE.dll not being present or registered.
                Debug.WriteLine("WDE: ProgramPublisher.PublisherThreadFunc() exception: " + e.ToString());
            }
        }

        public void Unpublish()
        {
            if (!isPublished)
                return;

            Debug.WriteLine("WDE: ProgramPublisher.Unpublish()");

            // In order to guarantee that the Program Nodes are always in the MTA, unpublish on a separate thread.
            try
            {
                Thread unpublisherThread = new Thread(UnpublishThreadFunc);
                unpublisherThread.SetApartmentState(ApartmentState.MTA);
                unpublisherThread.IsBackground = true;
                unpublisherThread.Start();
                unpublisherThread.Join();
            }
            catch (Exception e)
            {
                // Eat up exceptions if the debugger is not installed, etc.
                Debug.WriteLine("WDE: ProgramPublisher.Unpublish() exception: " + e.ToString());
            }

            Debug.WriteLine("WDE: ProgramPublisher.Unpublish() Done");
        }

        private void UnpublishThreadFunc()
        {
            try
            {
                this.publisher.Unpublish(this.wdeProgramNodeSingleton);
            }
            catch (Exception e)
            {
                Debug.WriteLine("WDE: ProgramPublisher.UnpublishThreadFunc(): catch exception " + e.ToString());
                // We eat up any exceptions that can occur because the host process is abnormally terminated.
            }
            finally
            {
                this.gchWdeProgramNode.Free(); // Rrelease pin on the this.wdeProgramNodeSingleton

                Marshal.ReleaseComObject(this.publisher);
                this.publisher = null;
            }

            this.isPublished = false;
        }

        #endregion
    }

    [ComImport(), Guid(Guids.IID_IWDEProgramPublisher), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IWDEProgramPublisher
    {
        void Publish([MarshalAs(UnmanagedType.IUnknown)] object ProgramNode);
        void Unpublish([MarshalAs(UnmanagedType.IUnknown)] object ProgramNode);
    }


}