private void RunVerifierThreadRoutine(object o) { RunVerifierThreadParams p = (RunVerifierThreadParams)o; RunVerifier(p.program, p.snapshot, p.requestId, p.errorListHolder, p.diagnoseTimeouts); }
/// <summary> /// This method is invoked when the user has been idle for a little while. /// Note, "sender" and "args" are allowed to be passed in as null--they are not used by this method. /// </summary> public void UponIdle(object sender, EventArgs args) { lock (this) { if (verificationInProgress) { // This UponIdle message came at an inopportune time--we've already kicked off a verification. // Just back off. resolver.UpdateErrorList(resolver.Snapshot); return; } if (resolver == null) { return; } Dafny.Program prog; ITextSnapshot snap; lock (resolver) { prog = resolver.Program; snap = resolver.Snapshot; } if (prog == null || VerificationDisabled) { return; } // We have a successfully resolved program to verify var dt = isDiagnosingTimeouts; if (!dt) { var resolvedVersion = snap.Version.VersionNumber; if (bufferChangesPostVerificationStart.Count == 0) { // Nothing new to verify. No reason to start a new verification. return; } else if (!bufferChangesPostVerificationStart.TrueForAll(span => span.Snapshot.Version.VersionNumber <= resolvedVersion)) { // There have been buffer changes since the program that was resolved. Do nothing here, // and instead just await the next resolved program. return; } } // at this time, we're committed to running the verifier lastRequestId = null; lock (RequestIdToSnapshot) { do { lastRequestId = DateTime.UtcNow.Ticks.ToString(); } while (RequestIdToSnapshot.ContainsKey(lastRequestId)); RequestIdToSnapshot[lastRequestId] = snap; } if (_document != null) { ProgressTaggers[_document.TextBuffer] = this; } RunVerifierThreadParams verifierThreadParams = new RunVerifierThreadParams(prog, snap, lastRequestId, resolver, dt); Thread thread = new Thread(RunVerifierThreadRoutine, _verificationTaskStackSize); thread.Start(verifierThreadParams); verificationInProgress = true; if (dt) { isDiagnosingTimeouts = false; } // Change orange progress markers into yellow ones Contract.Assert(bufferChangesPreVerificationStart.Count == 0); // follows from monitor invariant var empty = bufferChangesPreVerificationStart; bufferChangesPreVerificationStart = bufferChangesPostVerificationStart; bufferChangesPostVerificationStart = empty; // Notify to-whom-it-may-concern about the changes we just made NotifyAboutChangedTags(snap); } }