From 4f72d8965acbd329aac3d5e676ad695c059a4b24 Mon Sep 17 00:00:00 2001
From: Dmitry Simonenko <pmwkaa@gmail.com>
Date: Wed, 11 Dec 2013 17:03:56 +0400
Subject: [PATCH] gh-136: move any fiber yield out of catch block.

This is done to avoid situation, when two or more
fibers yield inside their try/catch blocks and
throws an exceptions. Seems like exception unwinder
stores some global state while being inside
a catch block.

This could lead to incorrect exception processing
and server crash.
---
 src/replica.cc | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/src/replica.cc b/src/replica.cc
index d4ce43956f..24ad427218 100644
--- a/src/replica.cc
+++ b/src/replica.cc
@@ -95,6 +95,7 @@ pull_from_remote(va_list ap)
 	struct ev_io coio;
 	struct iobuf *iobuf = NULL;
 	bool warning_said = false;
+	int reconnect_sleep = 0;
 	const int reconnect_delay = 1;
 
 	coio_init(&coio);
@@ -142,7 +143,25 @@ pull_from_remote(va_list ap)
 				warning_said = true;
 			}
 			evio_close(&coio);
+			reconnect_sleep = 1;
+		}
+
+		/* Put fiber_sleep() out of catch block.
+		 * 
+		 * This is done to avoid situation, when two or more
+		 * fibers yield's inside their try/catch blocks and
+		 * throws an exceptions. Seems like exception unwinder
+		 * stores some global state while being inside a catch
+		 * block.
+		 *
+		 * This could lead to incorrect exception processing
+		 * and crash the server.
+		 *
+		 * See: https://github.com/tarantool/tarantool/issues/136
+		*/
+		if (reconnect_sleep) {
 			fiber_sleep(reconnect_delay);
+			reconnect_sleep = 0;
 		}
 	}
 }
-- 
GitLab