Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 923be68441f6dcb7be63a4ac7c460d4b27c69942 (plain) (blame)
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
/*******************************************************************************
 * Copyright (c) 2006, 2008 Wind River Systems and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Wind River Systems - initial API and implementation
 *******************************************************************************/
package org.eclipse.cdt.examples.dsf.pda.ui.actions;

import java.util.concurrent.RejectedExecutionException;

import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.examples.dsf.pda.service.PDACommandControl;
import org.eclipse.cdt.examples.dsf.pda.service.PDAVirtualMachineDMContext;
import org.eclipse.cdt.examples.dsf.pda.ui.PDAUIPlugin;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.commands.IDebugCommandRequest;
import org.eclipse.debug.core.commands.IEnabledStateRequest;
import org.eclipse.debug.core.commands.ITerminateHandler;

/**
 * The terminate command is specialized for the PDA debugger.  Currently there
 * is no standard interface for terminating a debug session in DSF, because the 
 * details of initiating and shutting down a debug session vary greatly in 
 * different debuggers.
 */
public class PDATerminateCommand implements ITerminateHandler {
    // The executor and the services tracker, both initialized from a DSF session.
    private final DsfSession fSession;
    private final DsfServicesTracker fTracker;
    
    public PDATerminateCommand(DsfSession session) {
        fSession = session;
        fTracker = new DsfServicesTracker(PDAUIPlugin.getBundleContext(), session.getId());
    }    

    public void dispose() {
        // DSF services tracker always has to be disposed, because the OSGi services
        // use reference counting.
        fTracker.dispose();
    }

    // Run control may not be available after a connection is terminated and shut down.
    public void canExecute(final IEnabledStateRequest request) {
        // Terminate can only operate on a single element.
        if (request.getElements().length != 1 || 
            !(request.getElements()[0] instanceof IDMVMContext) ) 
        {
            request.setEnabled(false);
            request.done();
            return;
        }

        // Find the PDA program context in the selected element.  If one is not found, 
        // the action should be disabled.
        IDMVMContext vmc = (IDMVMContext)request.getElements()[0];
        final PDAVirtualMachineDMContext pdaProgramCtx = DMContexts.getAncestorOfType(vmc.getDMContext(), PDAVirtualMachineDMContext.class);
        if (pdaProgramCtx == null) {
            request.setEnabled(false);
            request.done();
            return;
        }            
        
        try {
            fSession.getExecutor().execute(
                new DsfRunnable() { 
                    public void run() {
                        // Get the processes service and the exec context.
                        PDACommandControl commandControl = fTracker.getService(PDACommandControl.class);
                        if (commandControl == null || pdaProgramCtx == null) {
                            // Context or service already invalid.
                            request.setEnabled(false);
                            request.done();
                        } else {
                            // Check whether the control is terminated.
                            request.setEnabled(!commandControl.isTerminated());
                            request.done();
                        }
                    }
                });
        } catch (RejectedExecutionException e) {
            // The DSF session for this context is no longer active.  It's possible to check 
            // for this condition before calling fSession.getExecutor().execute(), but 
            // since this method is executing in a different thread than the session control, 
            // there would still be a chance for a race condition leading to this exception. 
            request.setEnabled(false);
            request.done();
        }
    }

    public boolean execute(final IDebugCommandRequest request) {
        // Skip the checks and assume that this method is called only if the action
        // was enabled.

        try {
            fSession.getExecutor().submit(new DsfRunnable() { 
                public void run() {
                    // If the command control service is available, attempt to terminate the program.
                    PDACommandControl commandControl = fTracker.getService(PDACommandControl.class);
                    if (commandControl != null) {
                        
                        commandControl.terminate(
                            new RequestMonitor(ImmediateExecutor.getInstance(), null) {
                                @Override
                                protected void handleCompleted() {
                                    request.setStatus(getStatus());
                                    request.done();
                                }
                            });
                    }
                 }
            });
        } catch (RejectedExecutionException e) {
            request.setStatus(new Status(IStatus.ERROR, PDAUIPlugin.PLUGIN_ID, "PDA debug session is shut down."));
            request.done();
        }
        return false;
    }
    
}

Back to the top