From 44e81269a37633d144022dbbed8b62ce5d250932 Mon Sep 17 00:00:00 2001
From: John Preston <johnprestonmail@gmail.com>
Date: Mon, 29 Jun 2020 21:27:32 +0400
Subject: [PATCH] Fix assertion violation in event loop tracking.

---
 Telegram/SourceFiles/core/sandbox.cpp | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/Telegram/SourceFiles/core/sandbox.cpp b/Telegram/SourceFiles/core/sandbox.cpp
index 84ad8a6682..4ea9ab91a2 100644
--- a/Telegram/SourceFiles/core/sandbox.cpp
+++ b/Telegram/SourceFiles/core/sandbox.cpp
@@ -469,10 +469,7 @@ uint64 Sandbox::installationTag() const {
 	return _launcher->installationTag();
 }
 
-void Sandbox::postponeCall(FnMut<void()> &&callable) {
-	Expects(callable != nullptr);
-	Expects(_eventNestingLevel >= _loopNestingLevel);
-
+void Sandbox::checkForEmptyLoopNestingLevel() {
 	// _loopNestingLevel == _eventNestingLevel means that we had a
 	// native event in a nesting loop that didn't get a notify() call
 	// after. That means we already have exited the nesting loop and
@@ -485,11 +482,17 @@ void Sandbox::postponeCall(FnMut<void()> &&callable) {
 		_loopNestingLevel = _previousLoopNestingLevels.back();
 		_previousLoopNestingLevels.pop_back();
 	}
+}
 
+void Sandbox::postponeCall(FnMut<void()> &&callable) {
+	Expects(callable != nullptr);
+	Expects(_eventNestingLevel >= _loopNestingLevel);
+
+	checkForEmptyLoopNestingLevel();
 	_postponedCalls.push_back({
 		_loopNestingLevel,
 		std::move(callable)
-		});
+	});
 }
 
 void Sandbox::incrementEventNestingLevel() {
@@ -497,16 +500,23 @@ void Sandbox::incrementEventNestingLevel() {
 }
 
 void Sandbox::decrementEventNestingLevel() {
+	Expects(_eventNestingLevel >= _loopNestingLevel);
+
 	if (_eventNestingLevel == _loopNestingLevel) {
 		_loopNestingLevel = _previousLoopNestingLevels.back();
 		_previousLoopNestingLevels.pop_back();
 	}
 	const auto processTillLevel = _eventNestingLevel - 1;
 	processPostponedCalls(processTillLevel);
+	checkForEmptyLoopNestingLevel();
 	_eventNestingLevel = processTillLevel;
+
+	Ensures(_eventNestingLevel >= _loopNestingLevel);
 }
 
 void Sandbox::registerEnterFromEventLoop() {
+	Expects(_eventNestingLevel >= _loopNestingLevel);
+
 	if (_eventNestingLevel > _loopNestingLevel) {
 		_previousLoopNestingLevels.push_back(_loopNestingLevel);
 		_loopNestingLevel = _eventNestingLevel;