/*++ Copyright (c) 2015 Microsoft Corporation --*/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using Microsoft.Z3; namespace Microsoft.SolverFoundation.Plugin.Z3 { /// /// Thread that will wait until the query abort function returns true or /// the stop method is called. If the abort function returns true at some /// point it will issue a softCancel() call to Z3. /// internal class AbortWorker { #region Private Members /// The Z3 solver private Microsoft.Z3.Context _context; /// The abort function to use to check if we are aborted private Func _QueryAbortFunction; /// Flag indicating that worker should stop private bool _stop = false; /// Flag indicating that we have been sent an abort signal private bool _aborted = false; #endregion Private Members #region Construction /// /// Worker constructor taking a Z3 instance and a function to periodically /// check for aborts. /// /// Z3 instance /// method to call to check for aborts public AbortWorker(Context context, Func queryAbortFunction) { _context = context; _QueryAbortFunction = queryAbortFunction; } #endregion Construction #region Public Methods /// /// Stop the abort worker. /// public void Stop() { _stop = true; } /// /// Is true if we have been aborted. /// public bool Aborted { get { return _aborted; } } /// /// Starts the abort worker. The worker checks the abort method /// periodically until either it is stopped by a call to the Stop() /// method or it gets an abort signal. In the latter case it will /// issue a soft abort signal to Z3. /// public void Start() { // We go until someone stops us _stop = false; while (!_stop && !_QueryAbortFunction()) { // Wait for a while Thread.Sleep(10); } // If we were stopped on abort, cancel z3 if (!_stop) { _context.Interrupt(); _aborted = true; } } #endregion Public Methods } }