* Makefile.am:
[monodevelop.git] / extras / MonoDevelop.Debugger.Mdb / Mono.Debugging.Server.Mdb / RuntimeInvokeManager.cs
blob92a86fb61c012d7e753f4516e33a319d0dc8c133
1 // RuntimeInvokeManager.cs
2 //
3 // Author:
4 // Lluis Sanchez Gual <lluis@novell.com>
5 //
6 // Copyright (c) 2008 Novell, Inc (http://www.novell.com)
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 // THE SOFTWARE.
28 using System;
29 using System.Collections.Generic;
30 using ST = System.Threading;
31 using MD = Mono.Debugger;
32 using ML = Mono.Debugger.Languages;
34 namespace DebuggerServer
36 public class RuntimeInvokeManager
38 List<ST.WaitCallback> operationsToCancel = new List<ST.WaitCallback> ();
40 public ML.TargetObject Invoke (EvaluationContext ctx, ML.TargetFunctionType function,
41 ML.TargetStructObject object_argument,
42 params ML.TargetObject[] param_objects)
44 MD.RuntimeInvokeResult res;
45 bool aborted = false;
46 ST.WaitCallback abortOper;
48 lock (operationsToCancel) {
49 res = ctx.Thread.RuntimeInvoke (function, object_argument, param_objects, true, false);
51 abortOper = delegate {
52 lock (operationsToCancel) {
53 if (!aborted) {
54 aborted = true;
55 res.Abort ();
56 res.CompletedEvent.WaitOne ();
57 ctx.Thread.AbortInvocation ();
58 WaitToStop (ctx.Thread);
63 operationsToCancel.Add (abortOper);
66 if (ctx.Timeout != -1) {
67 if (!res.CompletedEvent.WaitOne (ctx.Timeout, false)) {
68 lock (operationsToCancel) {
69 operationsToCancel.Remove (abortOper);
70 ST.Monitor.PulseAll (operationsToCancel);
71 if (aborted) {
72 throw new EvaluatorException ("Aborted.");
74 else
75 aborted = true;
76 res.Abort ();
77 res.CompletedEvent.WaitOne ();
78 ctx.Thread.AbortInvocation ();
79 WaitToStop (ctx.Thread);
80 throw new TimeOutException ();
83 } else {
84 res.Wait ();
85 WaitToStop (ctx.Thread);
88 lock (operationsToCancel) {
89 operationsToCancel.Remove (abortOper);
90 ST.Monitor.PulseAll (operationsToCancel);
91 if (aborted) {
92 throw new EvaluatorException ("Aborted.");
96 if (res.ExceptionMessage != null) {
97 throw new Exception (res.ExceptionMessage);
100 return res.ReturnObject;
103 public void AbortAll ()
105 lock (operationsToCancel) {
106 foreach (ST.WaitCallback cb in operationsToCancel) {
107 try {
108 cb (null);
109 } catch {
110 // Ignore
113 operationsToCancel.Clear ();
117 public void WaitForAll ()
119 lock (operationsToCancel) {
120 while (operationsToCancel.Count > 0)
121 ST.Monitor.Wait (operationsToCancel);
125 void WaitToStop (MD.Thread thread)
127 thread.WaitHandle.WaitOne ();
128 while (!thread.IsStopped)
129 ST.Thread.Sleep (1);