/*++
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
}
}