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