From d454e06f6cbbd1590bcc8859b18c999792534abb Mon Sep 17 00:00:00 2001
From: Konstantin Osipov <kostja@tarantool.org>
Date: Sat, 12 Oct 2013 15:47:49 +0400
Subject: [PATCH] Fixes gh-51: onexit() is not portable.

Do not use atexit() handlers, except the global tarantool_free()
function, which does nothing in the snapshot process.
---
 include/memcached.h |  3 +++
 src/box/box.cc      |  1 -
 src/box/space.cc    |  2 ++
 src/memcached.cc    |  4 +---
 src/tarantool.cc    | 16 +++++++---------
 5 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/include/memcached.h b/include/memcached.h
index f9e536eefd..2c975791e6 100644
--- a/include/memcached.h
+++ b/include/memcached.h
@@ -35,6 +35,9 @@ struct tarantool_cfg;
 void
 memcached_init(const char *bind_ipaddr, int memcached_port);
 
+void
+memcached_free(void);
+
 void
 memcached_space_init();
 
diff --git a/src/box/box.cc b/src/box/box.cc
index 00bf4ed46d..a0c244bcf6 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -321,7 +321,6 @@ void
 box_init(bool init_storage)
 {
 	title("loading");
-	atexit(box_free);
 
 	/* initialization spaces */
 	space_init();
diff --git a/src/box/space.cc b/src/box/space.cc
index 3ee39e0ca8..304324d0a0 100644
--- a/src/box/space.cc
+++ b/src/box/space.cc
@@ -209,6 +209,8 @@ space_validate_tuple(struct space *sp, struct tuple *new_tuple)
 void
 space_free(void)
 {
+	if (spaces == NULL)
+		return;
 	while (mh_size(spaces) > 0) {
 		mh_int_t i = mh_first(spaces);
 
diff --git a/src/memcached.cc b/src/memcached.cc
index 1311fac54f..545bbeae8c 100644
--- a/src/memcached.cc
+++ b/src/memcached.cc
@@ -469,7 +469,7 @@ memcached_check_config(struct tarantool_cfg *conf)
 	return 0;
 }
 
-static void
+void
 memcached_free(void)
 {
 	if (memcached_it)
@@ -483,8 +483,6 @@ memcached_init(const char *bind_ipaddr, int memcached_port)
 	if (memcached_port == 0)
 		return;
 
-	atexit(memcached_free);
-
 	stat_base = stat_register(memcached_stat_strs, memcached_stat_MAX);
 
 	struct space *sp = space_by_n(cfg.memcached_space);
diff --git a/src/tarantool.cc b/src/tarantool.cc
index 03f8d913db..aa6bf66e29 100644
--- a/src/tarantool.cc
+++ b/src/tarantool.cc
@@ -316,12 +316,6 @@ tarantool_uptime(void)
 	return ev_now() - start_time;
 }
 
-void snapshot_exit(int code, void* arg) {
-	(void)arg;
-	fflush(NULL);
-	_exit(code);
-}
-
 int
 snapshot(void)
 {
@@ -360,7 +354,6 @@ snapshot(void)
 	 * may call exit(), push a top-level handler which will do
 	 * _exit() for us.
 	 */
-	on_exit(snapshot_exit, NULL);
 	snapshot_save(recovery_state, box_snapshot);
 
 	exit(EXIT_SUCCESS);
@@ -523,7 +516,6 @@ signal_init(void)
 	ev_signal_init(&sigs[3], signal_cb, SIGHUP);
 	ev_signal_start(&sigs[3]);
 
-	atexit(signal_free);
 	(void) tt_pthread_atfork(NULL, NULL, signal_reset);
 }
 
@@ -611,6 +603,13 @@ tarantool_lua_free()
 void
 tarantool_free(void)
 {
+	/* Do nothing in a fork. */
+	if (getpid() != master_pid)
+		return;
+	signal_free();
+	memcached_free();
+	tarantool_lua_free();
+	box_free();
 	recovery_free();
 	stat_free();
 
@@ -867,7 +866,6 @@ main(int argc, char **argv)
 		say_crit("version %s", tarantool_version());
 		tarantool_L = tarantool_lua_init();
 		box_init(false);
-		atexit(tarantool_lua_free);
 		memcached_init(cfg.bind_ipaddr, cfg.memcached_port);
 		tarantool_lua_load_cfg(tarantool_L, &cfg);
 		/*
-- 
GitLab