33
33
using System . Collections . Generic ;
34
34
using System . Runtime . CompilerServices ;
35
35
using System . Threading ;
36
-
36
+ using System . Threading . Tasks ;
37
37
using Mono . Debugger . Soft ;
38
38
using Mono . Debugging . Backend ;
39
39
using Mono . Debugging . Evaluation ;
@@ -2177,30 +2177,36 @@ static string MirrorStringToString (EvaluationContext ctx, StringMirror mirror)
2177
2177
}
2178
2178
}
2179
2179
2180
- class MethodCall : AsyncOperation
2180
+ internal class SoftOperationResult : OperationResult < Value >
2181
2181
{
2182
- readonly InvokeOptions options = InvokeOptions . DisableBreakpoints | InvokeOptions . SingleThreaded ;
2182
+ public SoftOperationResult ( Value result , bool resultIsException , Value [ ] outArgs ) : base ( result , resultIsException )
2183
+ {
2184
+ OutArgs = outArgs ;
2185
+ }
2186
+
2187
+ public Value [ ] OutArgs { get ; private set ; }
2188
+ }
2183
2189
2184
- readonly ManualResetEvent shutdownEvent = new ManualResetEvent ( false ) ;
2190
+ internal class SoftMethodCall : AsyncOperationBase < Value >
2191
+ {
2192
+ readonly InvokeOptions options = InvokeOptions . DisableBreakpoints | InvokeOptions . SingleThreaded ;
2185
2193
readonly SoftEvaluationContext ctx ;
2186
2194
readonly MethodMirror function ;
2187
2195
readonly Value [ ] args ;
2188
- readonly object obj ;
2189
- IAsyncResult handle ;
2190
- Exception exception ;
2191
- IInvokeResult result ;
2192
-
2193
- public MethodCall ( SoftEvaluationContext ctx , MethodMirror function , object obj , Value [ ] args , bool enableOutArgs )
2196
+ readonly IInvocableMethodOwnerMirror obj ;
2197
+ IInvokeAsyncResult invokeAsyncResult ;
2198
+
2199
+ public SoftMethodCall ( SoftEvaluationContext ctx , MethodMirror function , IInvocableMethodOwnerMirror obj , Value [ ] args , bool enableOutArgs )
2194
2200
{
2195
2201
this . ctx = ctx ;
2196
2202
this . function = function ;
2197
2203
this . obj = obj ;
2198
2204
this . args = args ;
2199
2205
if ( enableOutArgs ) {
2200
- this . options |= InvokeOptions . ReturnOutArgs ;
2206
+ options |= InvokeOptions . ReturnOutArgs ;
2201
2207
}
2202
2208
if ( function . VirtualMachine . Version . AtLeast ( 2 , 40 ) ) {
2203
- this . options |= InvokeOptions . Virtual ;
2209
+ options |= InvokeOptions . Virtual ;
2204
2210
}
2205
2211
}
2206
2212
@@ -2210,113 +2216,60 @@ public override string Description {
2210
2216
}
2211
2217
}
2212
2218
2213
- public override void Invoke ( )
2219
+ protected override void AfterCancelledImpl ( int elapsedAfterCancelMs )
2214
2220
{
2215
- try {
2216
- var invocableMirror = obj as IInvocableMethodOwnerMirror ;
2217
- if ( invocableMirror != null ) {
2218
- var optionsToInvoke = options ;
2219
- if ( obj is StructMirror ) {
2220
- optionsToInvoke |= InvokeOptions . ReturnOutThis ;
2221
- }
2222
- handle = invocableMirror . BeginInvokeMethod ( ctx . Thread , function , args , optionsToInvoke , null , null ) ;
2223
- }
2224
- else
2225
- throw new ArgumentException ( "Soft debugger method calls cannot be invoked on objects of type " + obj . GetType ( ) . Name ) ;
2226
- } catch ( InvocationException ex ) {
2227
- ctx . Session . StackVersion ++ ;
2228
- exception = ex ;
2229
- } catch ( Exception ex ) {
2230
- ctx . Session . StackVersion ++ ;
2231
- DebuggerLoggingService . LogError ( "Error in soft debugger method call thread on " + GetInfo ( ) , ex ) ;
2232
- exception = ex ;
2233
- }
2234
2221
}
2235
2222
2236
- public override void Abort ( )
2237
- {
2238
- if ( handle is IInvokeAsyncResult ) {
2239
- var info = GetInfo ( ) ;
2240
- DebuggerLoggingService . LogMessage ( "Aborting invocation of " + info ) ;
2241
- ( ( IInvokeAsyncResult ) handle ) . Abort ( ) ;
2242
- // Don't wait for the abort to finish. The engine will do it.
2243
- } else {
2244
- throw new NotSupportedException ( ) ;
2245
- }
2246
- }
2247
-
2248
- public override void Shutdown ( )
2249
- {
2250
- shutdownEvent . Set ( ) ;
2251
- }
2252
-
2253
- void EndInvoke ( )
2223
+ protected override Task < OperationResult < Value > > InvokeAsyncImpl ( CancellationToken token )
2254
2224
{
2255
2225
try {
2256
- result = ( ( IInvocableMethodOwnerMirror ) obj ) . EndInvokeMethodWithResult ( handle ) ;
2257
- } catch ( InvocationException ex ) {
2258
- if ( ! Aborting && ex . Exception != null ) {
2259
- string ename = ctx . Adapter . GetValueTypeName ( ctx , ex . Exception ) ;
2260
- var vref = ctx . Adapter . GetMember ( ctx , null , ex . Exception , "Message" ) ;
2261
-
2262
- exception = vref != null ? new Exception ( ename + ": " + ( string ) vref . ObjectValue ) : new Exception ( ename ) ;
2263
- return ;
2226
+ var optionsToInvoke = options ;
2227
+ if ( obj is StructMirror ) {
2228
+ optionsToInvoke |= InvokeOptions . ReturnOutThis ;
2264
2229
}
2265
- exception = ex ;
2266
- } catch ( Exception ex ) {
2267
- DebuggerLoggingService . LogError ( "Error in soft debugger method call thread on " + GetInfo ( ) , ex ) ;
2268
- exception = ex ;
2269
- } finally {
2270
- ctx . Session . StackVersion ++ ;
2271
- }
2272
- }
2273
-
2274
- string GetInfo ( )
2275
- {
2276
- try {
2277
- TypeMirror type = null ;
2278
- if ( obj is ObjectMirror )
2279
- type = ( ( ObjectMirror ) obj ) . Type ;
2280
- else if ( obj is TypeMirror )
2281
- type = ( TypeMirror ) obj ;
2282
- else if ( obj is StructMirror )
2283
- type = ( ( StructMirror ) obj ) . Type ;
2284
- return string . Format ( "method {0} on object {1}" ,
2285
- function == null ? "[null]" : function . FullName ,
2286
- type == null ? "[null]" : type . FullName ) ;
2287
- } catch ( Exception ex ) {
2288
- DebuggerLoggingService . LogError ( "Error getting info for SDB MethodCall" , ex ) ;
2289
- return "" ;
2230
+ var tcs = new TaskCompletionSource < OperationResult < Value > > ( ) ;
2231
+ invokeAsyncResult = ( IInvokeAsyncResult ) obj . BeginInvokeMethod ( ctx . Thread , function , args , optionsToInvoke , ar => {
2232
+ try {
2233
+ var endInvokeResult = obj . EndInvokeMethodWithResult ( ar ) ;
2234
+ token . ThrowIfCancellationRequested ( ) ;
2235
+ tcs . SetResult ( new SoftOperationResult ( endInvokeResult . Result , false , endInvokeResult . OutArgs ) ) ;
2236
+ }
2237
+ catch ( InvocationException ex ) {
2238
+ // throw OCE if cancelled
2239
+ token . ThrowIfCancellationRequested ( ) ;
2240
+ if ( ex . Exception != null ) {
2241
+ tcs . SetResult ( new SoftOperationResult ( ex . Exception , true , null ) ) ;
2242
+ }
2243
+ else {
2244
+ tcs . SetException ( new EvaluatorException ( "Target method has thrown an exception but the exception object is inaccessible" ) ) ;
2245
+ }
2246
+ }
2247
+ catch ( Exception e ) {
2248
+ tcs . SetException ( e ) ;
2249
+ }
2250
+ finally {
2251
+ UpdateSessionState ( ) ;
2252
+ }
2253
+ } , null ) ;
2254
+ return tcs . Task ;
2255
+ } catch ( Exception ) {
2256
+ UpdateSessionState ( ) ;
2257
+ throw ;
2290
2258
}
2291
2259
}
2292
2260
2293
- public override bool WaitForCompleted ( int timeout )
2261
+ void UpdateSessionState ( )
2294
2262
{
2295
- if ( handle == null )
2296
- return true ;
2297
- int res = WaitHandle . WaitAny ( new WaitHandle [ ] { handle . AsyncWaitHandle , shutdownEvent } , timeout ) ;
2298
- if ( res == 0 ) {
2299
- EndInvoke ( ) ;
2300
- return true ;
2301
- }
2302
- // Return true if shut down.
2303
- return res == 1 ;
2263
+ ctx . Session . StackVersion ++ ;
2304
2264
}
2305
2265
2306
- public Value ReturnValue {
2307
- get {
2308
- if ( exception != null )
2309
- throw new EvaluatorException ( exception . Message ) ;
2310
- return result . Result ;
2311
- }
2312
- }
2313
-
2314
- public Value [ ] OutArgs {
2315
- get {
2316
- if ( exception != null )
2317
- throw new EvaluatorException ( exception . Message ) ;
2318
- return result . OutArgs ;
2266
+ protected override void CancelImpl ( )
2267
+ {
2268
+ if ( invokeAsyncResult == null ) {
2269
+ DebuggerLoggingService . LogError ( "invokeAsyncResult is null" , new ArgumentNullException ( "invokeAsyncResult" ) ) ;
2270
+ return ;
2319
2271
}
2272
+ invokeAsyncResult . Abort ( ) ;
2320
2273
}
2321
2274
}
2322
2275
}
0 commit comments