private void Detach()
        {
            Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugController.Detach():"));

            using (new DebuggerThreadMarker())
            {
                lock (this.syncRoot)
                {

                    AppDomain.CurrentDomain.AssemblyLoad -= OnAssemblyLoad;

                    // See comments in Attach().
                    if (this.isZombie || !this.isAttached)
                        return;

                    this.isAttached = false;

                    // Undone: AkashS - At this point wait for all event handling to complete to avoid exceptions.

                    this.programId = Guid.Empty;

                    if (this.debugControllerThread != null)
                    {
                        this.debugControllerThread.StopThread();
                        this.debugControllerThread = null;
                    }

                    if (this.attachTimer != null)
                    {
                        this.attachTimer.Change(Timeout.Infinite, Timeout.Infinite);
                        this.attachTimer = null;
                    }

                    RemotingServices.Disconnect(this);
                    if (this.channel != null)
                    {
                        ChannelServices.UnregisterChannel(this.channel);
                        this.channel = null;
                    }

                    this.controllerConduit = null;

                    this.eventConduitAttached.Reset();
                    this.instanceTable = null;
                    this.typeToGuid = null;
                    this.xomlHashToGuid = null;

                    // Do this only after we perform the previous cleanup! Otherwise
                    // we may get exceptions from the runtime that may cause the cleanup
                    // to not happen.

                    if (!this.serviceContainer.IsZombie)
                    {
                        foreach (WorkflowInstance instance in this.serviceContainer.GetLoadedWorkflows())
                        {
                            WorkflowExecutor executor = instance.GetWorkflowResourceUNSAFE();
                            using (executor.ExecutorLock.Enter())
                            {
                                if (executor.IsInstanceValid)
                                    executor.WorkflowExecutionEvent -= OnInstanceEvent;
                            }
                        }

                        this.serviceContainer.WorkflowExecutorInitializing -= InstanceInitializing;
                        this.serviceContainer.DefinitionDispenser.WorkflowDefinitionLoaded -= ScheduleTypeLoaded;
                    }
                }
            }
        }
 internal void Attach(Guid programId, int attachTimeout, int detachPingInterval, out string hostName, out string uri, out int controllerThreadId, out bool isSynchronousAttach)
 {
     lock (this.syncRoot)
     {
         hostName = string.Empty;
         uri = string.Empty;
         controllerThreadId = 0;
         isSynchronousAttach = false;
         if (!this.isZombie)
         {
             if (this.isAttached)
             {
                 this.Detach();
             }
             this.isAttached = true;
             this.programId = programId;
             this.debugControllerThread = new DebugControllerThread();
             this.instanceTable = new InstanceTable(this.debugControllerThread.ManagedThreadId);
             this.typeToGuid = new Dictionary<Type, Guid>();
             this.xomlHashToGuid = new Dictionary<byte[], Guid>(new DigestComparer());
             this.debugControllerThread.RunThread(this.instanceTable);
             IDictionary properties = new Hashtable();
             properties["typeFilterLevel"] = "Full";
             BinaryServerFormatterSinkProvider serverSinkProvider = new BinaryServerFormatterSinkProvider(properties, null);
             Hashtable hashtable = new Hashtable();
             hashtable["name"] = string.Empty;
             hashtable["portName"] = this.programId.ToString();
             IdentityReference reference = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null).Translate(typeof(NTAccount));
             hashtable["authorizedGroup"] = reference.ToString();
             this.channel = new IpcChannel(hashtable, null, serverSinkProvider);
             ChannelServices.RegisterChannel(this.channel, true);
             RemotingServices.Marshal(this, this.programId.ToString());
             hostName = this.hostName;
             uri = this.channel.GetUrlsForUri(this.programId.ToString())[0];
             controllerThreadId = this.debugControllerThread.ThreadId;
             isSynchronousAttach = !this.isServiceContainerStarting;
             this.attachTimeout = attachTimeout;
             this.attachTimer = new Timer(new TimerCallback(this.AttachTimerCallback), null, attachTimeout, detachPingInterval);
         }
     }
 }
        internal void Attach(Guid programId, int attachTimeout, int detachPingInterval, out string hostName, out string uri, out int controllerThreadId, out bool isSynchronousAttach)
        {
            Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugController.Attach(): programId = {0}", programId));
            lock (this.syncRoot)
            {
                hostName = String.Empty;
                uri = String.Empty;
                controllerThreadId = 0;
                isSynchronousAttach = false;

                // Race condition:
                // During the call to Attach() if Uninitialize() is also called, we should ignore the call to Attach() and
                // just return. The Zombie flag and lock(this) help us recognize the ----.
                if (this.isZombie)
                    return;


                // Race condition:
                // The isAttached flat along with lock(this) catch the ---- where a debugger may have detached which
                // we haven't detected yet and another debugger may have attached, so we force detach from the first
                // debugger.
                if (this.isAttached)
                    Detach();


                this.isAttached = true;

                this.programId = programId;
                this.debugControllerThread = new DebugControllerThread();
                this.instanceTable = new InstanceTable(this.debugControllerThread.ManagedThreadId);
                this.typeToGuid = new Dictionary<Type, Guid>();
                this.xomlHashToGuid = new Dictionary<byte[], Guid>((IEqualityComparer<byte[]>)new DigestComparer());

                this.debugControllerThread.RunThread(this.instanceTable);

                // Publish our MBR object.
                IDictionary providerProperties = new Hashtable();
                providerProperties["typeFilterLevel"] = "Full";
                BinaryServerFormatterSinkProvider sinkProvider = new BinaryServerFormatterSinkProvider(providerProperties, null);

                Hashtable channelProperties = new Hashtable();
                channelProperties["name"] = string.Empty;
                channelProperties["portName"] = this.programId.ToString();
                SecurityIdentifier si = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);
                IdentityReference idRef = si.Translate(typeof(NTAccount));
                channelProperties["authorizedGroup"] = idRef.ToString();
                this.channel = new IpcChannel(channelProperties, null, sinkProvider);
                ChannelServices.RegisterChannel(this.channel, true);

                ObjRef o = RemotingServices.Marshal(this, this.programId.ToString());
                hostName = this.hostName;

                uri = this.channel.GetUrlsForUri(this.programId.ToString())[0];
                controllerThreadId = this.debugControllerThread.ThreadId;
                isSynchronousAttach = !this.isServiceContainerStarting;

                this.attachTimeout = attachTimeout;
                this.attachTimer = new Timer(AttachTimerCallback, null, attachTimeout, detachPingInterval);
            }
        }
 private void Detach()
 {
     using (new DebuggerThreadMarker())
     {
         lock (this.syncRoot)
         {
             AppDomain.CurrentDomain.AssemblyLoad -= new AssemblyLoadEventHandler(this.OnAssemblyLoad);
             if (!this.isZombie && this.isAttached)
             {
                 this.isAttached = false;
                 this.programId = Guid.Empty;
                 if (this.debugControllerThread != null)
                 {
                     this.debugControllerThread.StopThread();
                     this.debugControllerThread = null;
                 }
                 if (this.attachTimer != null)
                 {
                     this.attachTimer.Change(-1, -1);
                     this.attachTimer = null;
                 }
                 RemotingServices.Disconnect(this);
                 if (this.channel != null)
                 {
                     ChannelServices.UnregisterChannel(this.channel);
                     this.channel = null;
                 }
                 this.controllerConduit = null;
                 this.eventConduitAttached.Reset();
                 this.instanceTable = null;
                 this.typeToGuid = null;
                 this.xomlHashToGuid = null;
                 if (!this.serviceContainer.IsZombie)
                 {
                     foreach (WorkflowInstance instance in this.serviceContainer.GetLoadedWorkflows())
                     {
                         WorkflowExecutor workflowResourceUNSAFE = instance.GetWorkflowResourceUNSAFE();
                         using (workflowResourceUNSAFE.ExecutorLock.Enter())
                         {
                             if (workflowResourceUNSAFE.IsInstanceValid)
                             {
                                 workflowResourceUNSAFE.WorkflowExecutionEvent -= new EventHandler<WorkflowExecutor.WorkflowExecutionEventArgs>(this.OnInstanceEvent);
                             }
                         }
                     }
                     this.serviceContainer.WorkflowExecutorInitializing -= new EventHandler<WorkflowRuntime.WorkflowExecutorInitializingEventArgs>(this.InstanceInitializing);
                     this.serviceContainer.DefinitionDispenser.WorkflowDefinitionLoaded -= new EventHandler<WorkflowDefinitionEventArgs>(this.ScheduleTypeLoaded);
                 }
             }
         }
     }
 }