@@ -19,7 +19,7 @@ type internal IReactorOperations =
1919[<NoEquality; NoComparison>]
2020type internal ReactorCommands =
2121/// Kick off a build.
22- | SetBackgroundOpof ( (* userOpName:*) string * (* opName:*) string * (* opArg:*) string * ( CompilationThreadToken -> bool )) option
22+ | SetBackgroundOpof ( (* userOpName:*) string * (* opName:*) string * (* opArg:*) string * ( CompilationThreadToken -> CancellationToken -> bool )) option
2323/// Do some work not synchronized in the mailbox.
2424| Opof userOpName : string * opName : string * opArg : string * CancellationToken * ( CompilationThreadToken -> unit ) * ( unit -> unit )
2525/// Finish the background building
@@ -39,6 +39,7 @@ type Reactor() =
3939// so that when the reactor picks up a thread from the threadpool we can set the culture
4040let culture = new CultureInfo( CultureInfo.CurrentUICulture.Name)
4141
42+ let mutable bgOpCts = new CancellationTokenSource()
4243/// Mailbox dispatch function.
4344let builder =
4445 MailboxProcessor<_>. Start<| fun inbox ->
@@ -74,6 +75,7 @@ type Reactor() =
7475| Some( SetBackgroundOp bgOpOpt) ->
7576//Trace.TraceInformation("Reactor: --> set background op, remaining {0}", inbox.CurrentQueueLength)
7677return ! loop( bgOpOpt, onComplete, false )
78+
7779| Some( Op( userOpName, opName, opArg, ct, op, ccont)) ->
7880if ct.IsCancellationRequestedthen ccont() else
7981 Trace.TraceInformation( " Reactor: {0:n3} --> {1}.{2} ({3}), remaining {4}" , DateTime.Now.TimeOfDay.TotalSeconds, userOpName, opName, opArg, inbox.CurrentQueueLength)
@@ -92,21 +94,33 @@ type Reactor() =
9294| None-> ()
9395| Some( bgUserOpName, bgOpName, bgOpArg, bgOp) ->
9496 Trace.TraceInformation( " Reactor: {0:n3} --> wait for background {1}.{2} ({3}), remaining {4}" , DateTime.Now.TimeOfDay.TotalSeconds, bgUserOpName, bgOpName, bgOpArg, inbox.CurrentQueueLength)
95- while bgOp ctokdo
97+ bgOpCts.Dispose()
98+ bgOpCts<- new CancellationTokenSource()
99+ while not bgOpCts.IsCancellationRequested&& bgOp ctok bgOpCts.Tokendo
96100()
101+
102+ if bgOpCts.IsCancellationRequestedthen
103+ Trace.TraceInformation( " FCS: <-- wait for background was cancelled {0}.{1}" , bgUserOpName, bgOpName)
104+
97105 channel.Reply(())
98106return ! loop( None, onComplete, false )
107+
99108| Some( CompleteAllQueuedOps channel) ->
100109 Trace.TraceInformation( " Reactor: {0:n3} --> stop background work and complete all queued ops, remaining {1}" , DateTime.Now.TimeOfDay.TotalSeconds, inbox.CurrentQueueLength)
101110return ! loop( None, Some channel, false )
111+
102112| None->
103113match bgOpOpt, onCompletewith
104114| _, Some onComplete-> onComplete.Reply()
105115| Some( bgUserOpName, bgOpName, bgOpArg, bgOp), None->
106116 Trace.TraceInformation( " Reactor: {0:n3} --> background step {1}.{2} ({3})" , DateTime.Now.TimeOfDay.TotalSeconds, bgUserOpName, bgOpName, bgOpArg)
107117let time = Stopwatch()
108118 time.Start()
109- let res = bgOp ctok
119+ bgOpCts.Dispose()
120+ bgOpCts<- new CancellationTokenSource()
121+ let res = bgOp ctok bgOpCts.Token
122+ if bgOpCts.IsCancellationRequestedthen
123+ Trace.TraceInformation( " FCS: <-- background step {0}.{1}, was cancelled" , bgUserOpName, bgOpName)
110124 time.Stop()
111125let taken = time.Elapsed.TotalMilliseconds
112126//if span.TotalMilliseconds > 100.0 then
@@ -126,8 +140,13 @@ type Reactor() =
126140// [Foreground Mailbox Accessors] -----------------------------------------------------------
127141member r.SetBackgroundOp ( bgOpOpt ) =
128142 Trace.TraceInformation( " Reactor: {0:n3} enqueue start background, length {1}" , DateTime.Now.TimeOfDay.TotalSeconds, builder.CurrentQueueLength)
143+ bgOpCts.Cancel()
129144 builder.Post( SetBackgroundOp bgOpOpt)
130145
146+ member r.CancelBackgroundOp () =
147+ Trace.TraceInformation( " FCS: trying to cancel any active background work" )
148+ bgOpCts.Cancel()
149+
131150member r.EnqueueOp ( userOpName , opName , opArg , op ) =
132151 Trace.TraceInformation( " Reactor: {0:n3} enqueue {1}.{2} ({3}), length {4}" , DateTime.Now.TimeOfDay.TotalSeconds, userOpName, opName, opArg, builder.CurrentQueueLength)
133152 builder.Post( Op( userOpName, opName, opArg, CancellationToken.None, op, ( fun () -> ())))