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