diff --git a/cfg/tarantool_box_cfg.c b/cfg/tarantool_box_cfg.c
index 2924909e017906eded4ee0697636f28b56212ef9..9ac4a967e7c273ee12020ff76822b4b8b010cf43 100644
--- a/cfg/tarantool_box_cfg.c
+++ b/cfg/tarantool_box_cfg.c
@@ -112,6 +112,13 @@ fill_default_tarantool_cfg(tarantool_cfg *c) {
 	return 0;
 }
 
+void
+swap_tarantool_cfg(struct tarantool_cfg *c1, struct tarantool_cfg *c2) {
+	struct tarantool_cfg tmpcfg = *c1;
+	*c1 = *c2;
+	*c2 = tmpcfg;
+}
+
 static int
 acceptDefault_name__namespace(tarantool_cfg_namespace *c) {
 	c->enabled = -1;
diff --git a/cfg/tarantool_box_cfg.h b/cfg/tarantool_box_cfg.h
index d1d777b2fe4cf3138ba63c1615874805cb3bd5c3..44a9c4a1b27f16485073d5a9eb7534deb31dfb5b 100644
--- a/cfg/tarantool_box_cfg.h
+++ b/cfg/tarantool_box_cfg.h
@@ -174,6 +174,8 @@ void init_tarantool_cfg(tarantool_cfg *c);
 
 int fill_default_tarantool_cfg(tarantool_cfg *c);
 
+void swap_tarantool_cfg(struct tarantool_cfg *c1, struct tarantool_cfg *c2);
+
 void parse_cfg_file_tarantool_cfg(tarantool_cfg *c, FILE *fh, int check_rdonly, int *n_accepted, int *n_skipped);
 
 void parse_cfg_buffer_tarantool_cfg(tarantool_cfg *c, char *buffer, int check_rdonly, int *n_accepted, int *n_skipped);
diff --git a/cfg/tarantool_feeder_cfg.c b/cfg/tarantool_feeder_cfg.c
index c1119f2157fda5eb9ddde5cdb6d0a1b2fb917430..3f5fb82f1f76f89b82bb06505d7c8671b3a8e58f 100644
--- a/cfg/tarantool_feeder_cfg.c
+++ b/cfg/tarantool_feeder_cfg.c
@@ -74,6 +74,13 @@ fill_default_tarantool_cfg(tarantool_cfg *c) {
 	return 0;
 }
 
+void
+swap_tarantool_cfg(struct tarantool_cfg *c1, struct tarantool_cfg *c2) {
+	struct tarantool_cfg tmpcfg = *c1;
+	*c1 = *c2;
+	*c2 = tmpcfg;
+}
+
 static NameAtom _name__username[] = {
 	{ "username", -1, NULL }
 };
diff --git a/cfg/tarantool_feeder_cfg.h b/cfg/tarantool_feeder_cfg.h
index 8384d02ded333f1a3e3d2963956fe4170c14359d..8296b42de4bee483f5a763bd6da5c467548846d2 100644
--- a/cfg/tarantool_feeder_cfg.h
+++ b/cfg/tarantool_feeder_cfg.h
@@ -90,6 +90,8 @@ void init_tarantool_cfg(tarantool_cfg *c);
 
 int fill_default_tarantool_cfg(tarantool_cfg *c);
 
+void swap_tarantool_cfg(struct tarantool_cfg *c1, struct tarantool_cfg *c2);
+
 void parse_cfg_file_tarantool_cfg(tarantool_cfg *c, FILE *fh, int check_rdonly, int *n_accepted, int *n_skipped);
 
 void parse_cfg_buffer_tarantool_cfg(tarantool_cfg *c, char *buffer, int check_rdonly, int *n_accepted, int *n_skipped);
diff --git a/core/fiber.m b/core/fiber.m
index d0c81026cd3297acc3179505cbe2507f873621b2..682f68079cffe8aabe8576a7dc785ec314d1a633 100644
--- a/core/fiber.m
+++ b/core/fiber.m
@@ -56,7 +56,7 @@
 #include <pickle.h>
 #include "diagnostics.h"
 
-@implementation tnt_FiberException
+@implementation tnt_FiberCancelException
 @end
 
 static struct fiber sched;
@@ -134,22 +134,23 @@ fiber_wakeup(struct fiber *f)
 	ev_async_send(&f->async);
 }
 
-/** Cancel the subject fiber. 
+/** Cancel the subject fiber.
  *
  * Note: this is not guaranteed to succeed, and requires a level
- * of cooperation on behalf of the fiber. A fiber may opt to 
- * set FIBER_CANCELLABLE to false, and never test that it was cancelled.
- * Such fiber we won't be ever to cancel, ever, and for such fiber
- * this call will lead to an infinite wait.
- * However, fiber_testcancel() is embedded to the rest of fiber_* API
- * (@sa yield()), which makes most of the fibers that opt in, cancellable.
+ * of cooperation on behalf of the fiber. A fiber may opt to set
+ * FIBER_CANCELLABLE to false, and never test that it was
+ * cancelled.  Such fiber we won't be ever to cancel, ever, and
+ * for such fiber this call will lead to an infinite wait.
+ * However, fiber_testcancel() is embedded to the rest of fiber_*
+ * API (@sa yield()), which makes most of the fibers that opt in,
+ * cancellable.
  *
- * Currently cancellation can only be synchronous: this call returns
- * only when the subject fiber has terminated. 
+ * Currently cancellation can only be synchronous: this call
+ * returns only when the subject fiber has terminated.
  *
- * The fiber which is cancelled, has tnt_FiberException raised in it. 
- * For cancellation to work, this exception type should be re-raised
- * whenever (if) it is caught.
+ * The fiber which is cancelled, has tnt_FiberCancelException
+ * raised in it. For cancellation to work, this exception type
+ * should be re-raised whenever (if) it is caught.
  */
 
 void
@@ -175,8 +176,9 @@ fiber_cancel(struct fiber *f)
 }
 
 
-/** Test if this fiber is in a cancellable state and was indeed cancelled,
- * and raise an exception (tnt_FiberException) if that's the case.
+/** Test if this fiber is in a cancellable state and was indeed
+ * cancelled, and raise an exception (tnt_FiberCancelException) if
+ * that's the case.
  */
 
 void
@@ -188,11 +190,11 @@ fiber_testcancel(void)
 	if (!(fiber->flags & FIBER_CANCEL))
 		return;
 
-	tnt_raise(tnt_FiberException, reason:"fiber_testcancel: fiber to be canceled");
+	tnt_raise(tnt_FiberCancelException, reason:"fiber_testcancel");
 }
 
-/** Change the current cancellation state of a fiber. 
- * This is not a cancellation point.
+/** Change the current cancellation state of a fiber. This is not
+ * a cancellation point.
  */
 
 void fiber_setcancelstate(bool enable)
@@ -274,7 +276,14 @@ wait_for(int events)
 	if (!ev_is_active(io))
 		ev_io_start(io);
 
-	yield();
+	@try {
+		yield();
+	}
+	@catch (id o)
+	{
+		ev_io_stop(io);
+		@throw;
+	}
 }
 
 static void
@@ -430,14 +439,13 @@ fiber_zombificate()
 static void
 fiber_loop(void *data __attribute__((unused)))
 {
-	while (42) {
+	while (true) {
 		assert(fiber != NULL && fiber->f != NULL && fiber->fid != 0);
 		@try {
 			fiber->f(fiber->f_data);
 		}
-		@catch (tnt_FiberException *e) {
-			say_info("fiber `%s': exception `tnt_FiberException': `%s'",
-				 fiber->name, e->reason);
+		@catch (tnt_FiberCancelException *e) {
+			say_info("fiber `%s' has been cancelled", fiber->name);
 
 			if (fiber->waiter != NULL) {
 				fiber_call(fiber->waiter);
@@ -463,8 +471,10 @@ fiber_loop(void *data __attribute__((unused)))
 	}
 }
 
-/** Set fiber name. 
-* @Param[in] name the new name of the fiber. Truncated to FIBER_NAME_MAXLEN.
+/** Set fiber name.
+ *
+ * @param[in] name the new name of the fiber. Truncated to
+ * FIBER_NAME_MAXLEN.
 */
 
 void
@@ -676,24 +686,20 @@ fiber_bread(struct tbuf *buf, size_t at_least)
 	ssize_t r;
 	tbuf_ensure(buf, MAX(cfg.readahead, at_least));
 
-	@try {
-		for (;;) {
-			wait_for(EV_READ);
-			r = read(fiber->fd, buf->data + buf->len, buf->size - buf->len);
-			if (r > 0) {
-				buf->len += r;
-				if (buf->len >= at_least)
-					break;
-			} else {
-				if (r < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))
-					continue;
+	for (;;) {
+		wait_for(EV_READ);
+		r = read(fiber->fd, buf->data + buf->len, buf->size - buf->len);
+		if (r > 0) {
+			buf->len += r;
+			if (buf->len >= at_least)
 				break;
-			}
+		} else {
+			if (r < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))
+				continue;
+			break;
 		}
 	}
-	@finally {
-		unwait(EV_READ);
-	}
+	unwait(EV_READ);
 
 	return r;
 }
@@ -717,33 +723,29 @@ fiber_flush_output(void)
 	struct iovec *iov = iovec(fiber->iov);
 	size_t iov_cnt = fiber->iov_cnt;
 
-	@try {
-		while (iov_cnt > 0) {
-			wait_for(EV_WRITE);
-			bytes += r = writev(fiber->fd, iov, MIN(iov_cnt, IOV_MAX));
-			if (r <= 0) {
-				if (errno == EAGAIN || errno == EWOULDBLOCK)
-					continue;
-				else
-					break;
-			}
+	while (iov_cnt > 0) {
+		wait_for(EV_WRITE);
+		bytes += r = writev(fiber->fd, iov, MIN(iov_cnt, IOV_MAX));
+		if (r <= 0) {
+			if (errno == EAGAIN || errno == EWOULDBLOCK)
+				continue;
+			else
+				break;
+		}
 
-			while (iov_cnt > 0) {
-				if (iov->iov_len > r) {
-					iov->iov_base += r;
-					iov->iov_len -= r;
-					break;
-				} else {
-					r -= iov->iov_len;
-					iov++;
-					iov_cnt--;
-				}
+		while (iov_cnt > 0) {
+			if (iov->iov_len > r) {
+				iov->iov_base += r;
+				iov->iov_len -= r;
+				break;
+			} else {
+				r -= iov->iov_len;
+				iov++;
+				iov_cnt--;
 			}
 		}
 	}
-	@finally {
-		unwait(EV_WRITE);
-	}
+	unwait(EV_WRITE);
 
 	if (r < 0) {
 		size_t rem = 0;
@@ -772,22 +774,18 @@ fiber_read(void *buf, size_t count)
 	if (count == 0)
 		return 0;
 
-	@try {
-		while (count != done) {
-			wait_for(EV_READ);
-
-			if ((r = read(fiber->fd, buf + done, count - done)) <= 0) {
-				if (errno == EAGAIN || errno == EWOULDBLOCK)
-					continue;
-				else
-					break;
-			}
-			done += r;
+	while (count != done) {
+		wait_for(EV_READ);
+
+		if ((r = read(fiber->fd, buf + done, count - done)) <= 0) {
+			if (errno == EAGAIN || errno == EWOULDBLOCK)
+				continue;
+			else
+				break;
 		}
+		done += r;
 	}
-	@finally {
-		unwait(EV_READ);
-	}
+	unwait(EV_READ);
 
 	return done;
 }
@@ -805,21 +803,17 @@ fiber_write(const void *buf, size_t count)
 	if (count == 0)
 		return 0;
 
-	@try {
-		while (count != done) {
-			wait_for(EV_WRITE);
-			if ((r = write(fiber->fd, buf + done, count - done)) == -1) {
-				if (errno == EAGAIN || errno == EWOULDBLOCK)
-					continue;
-				else
-					break;
-			}
-			done += r;
+	while (count != done) {
+		wait_for(EV_WRITE);
+		if ((r = write(fiber->fd, buf + done, count - done)) == -1) {
+			if (errno == EAGAIN || errno == EWOULDBLOCK)
+				continue;
+			else
+				break;
 		}
+		done += r;
 	}
-	@finally {
-		unwait(EV_WRITE);
-	}
+	unwait(EV_WRITE);
 
 	return done;
 }
@@ -846,21 +840,17 @@ fiber_connect(struct sockaddr_in *addr)
 			goto error;
 	}
 
-	@try {
-		wait_for(EV_WRITE);
-		if (getsockopt(fiber->fd, SOL_SOCKET, SO_ERROR, &error, &error_size) < 0)
-			goto error;
+	wait_for(EV_WRITE);
+	if (getsockopt(fiber->fd, SOL_SOCKET, SO_ERROR, &error, &error_size) < 0)
+		goto error;
 
-		assert(error_size == sizeof(error));
+	assert(error_size == sizeof(error));
 
-		if (error != 0) {
-			errno = error;
-			goto error;
-		}
-	}
-	@finally {
-		unwait(EV_WRITE);
+	if (error != 0) {
+		errno = error;
+		goto error;
 	}
+	unwait(EV_WRITE);
 
 	return fiber->fd;
 
@@ -1153,42 +1143,38 @@ tcp_server_handler(void *data)
 	if (server->on_bind != NULL)
 		server->on_bind(server->data);
 
-	@try {
-		while (1) {
-			wait_for(EV_READ);
-
-				while ((fd = accept(fiber->fd, NULL, NULL)) > 0) {
-					if (set_nonblock(fd) == -1) {
-						say_error("can't set nonblock");
-						close(fd);
-						continue;
-					}
-					if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
-						       &one, sizeof(one)) == -1) {
-						say_syserror("setsockopt failed");
-						/* Do nothing, not a fatal error.  */
-					}
-
-					snprintf(name, sizeof(name), "%i/handler", server->port);
-					h = fiber_create(name, fd, -1, server->handler, data);
-					if (h == NULL) {
-						say_error("can't create handler fiber, dropping client connection");
-						close(fd);
-						continue;
-					}
-
-					h->has_peer = true;
-					fiber_call(h);
-				}
-				if (fd < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
-					say_syserror("accept");
-					continue;
-				}
+	while (1) {
+		wait_for(EV_READ);
+
+		while ((fd = accept(fiber->fd, NULL, NULL)) > 0) {
+			if (set_nonblock(fd) == -1) {
+				say_error("can't set nonblock");
+				close(fd);
+				continue;
+			}
+			if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
+				       &one, sizeof(one)) == -1) {
+				say_syserror("setsockopt failed");
+				/* Do nothing, not a fatal error.  */
+			}
+
+			snprintf(name, sizeof(name), "%i/handler", server->port);
+			h = fiber_create(name, fd, -1, server->handler, data);
+			if (h == NULL) {
+				say_error("can't create handler fiber, dropping client connection");
+				close(fd);
+				continue;
+			}
+
+			h->has_peer = true;
+			fiber_call(h);
+		}
+		if (fd < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
+			say_syserror("accept");
+			continue;
 		}
 	}
-	@finally {
-		unwait(EV_READ);
-	}
+	unwait(EV_READ);
 }
 
 struct fiber *
diff --git a/core/tarantool.m b/core/tarantool.m
index 0483df8d7056e124a325dd9b7e341cd64a8c1167..d8e5f2a64f119713453fa0f880c3824dd3949b2f 100644
--- a/core/tarantool.m
+++ b/core/tarantool.m
@@ -100,15 +100,6 @@ load_cfg(struct tarantool_cfg *conf, i32 check_rdonly)
 	return mod_check_config(conf);
 }
 
-static void
-swap_tarantool_cfg(struct tarantool_cfg *old_cfg, struct tarantool_cfg *new_cfg)
-{
-	struct tarantool_cfg tmp;
-
-	tmp = *old_cfg;
-	*old_cfg = *new_cfg;
-	*new_cfg = tmp;
-}
 
 i32
 reload_cfg(struct tbuf *out)
@@ -134,10 +125,10 @@ reload_cfg(struct tbuf *out)
 
 		/*
 		  Prepare a copy of the original config file
-		  for confetti, so that it can compare the new 
+		  for confetti, so that it can compare the new
 		  file with the old one when loading the new file.
-		  Load the new file and return an error if the it
-		  contains  a different value for some read-only
+		  Load the new file and return an error if it
+		  contains a different value for some read-only
 		  parameter.
 		*/
 		if (dup_tarantool_cfg(&aux_cfg, &cfg) != 0 ||
@@ -145,8 +136,8 @@ reload_cfg(struct tbuf *out)
 			return -1;
 		/*
 		  Load the new configuration file, but
-		  skip the check for read only parameters. 
-		  new_cfg contains only defaults and 
+		  skip the check for read only parameters.
+		  new_cfg contains only defaults and
 		  new settings.
 		*/
 		if (fill_default_tarantool_cfg(&new_cfg) != 0 ||
diff --git a/include/exceptions.h b/include/exceptions.h
index f78206c65d14d836156612270f8a18cc0885a249..52dc6eee54d7dfb9822b7c9b08cb3a381eb99ea2 100644
--- a/include/exceptions.h
+++ b/include/exceptions.h
@@ -3,6 +3,12 @@
 
 #include <objc/Object.h>
 
+/** The base class for all exceptions.
+ *
+ * Note: implements garbage collection (see +alloc
+ * implementation).
+ */
+
 @interface tnt_Exception: Object {
 	@public
 		const char *file;
diff --git a/include/fiber.h b/include/fiber.h
index c04d24eca28d40ae4cd570621c9c476f1c758241..08f259eb90fbe23ec52bedf18c6dd18e7bf8079f 100644
--- a/include/fiber.h
+++ b/include/fiber.h
@@ -45,10 +45,16 @@
 #define FIBER_NAME_MAXLEN 16
 
 #define FIBER_READING_INBOX 0x1
+/** Can this fiber be cancelled? */
 #define FIBER_CANCELLABLE   0x2
+/** Indicates that a fiber has been cancelled. */
 #define FIBER_CANCEL        0x4
 
-@interface tnt_FiberException: tnt_Exception
+/** This is thrown by fiber_* API calls when the fiber is
+ * cancelled.
+ */
+
+@interface tnt_FiberCancelException: tnt_Exception
 @end
 
 struct msg {
@@ -165,8 +171,20 @@ void fiber_cleanup(void);
 void fiber_gc(void);
 void fiber_call(struct fiber *callee);
 void fiber_wakeup(struct fiber *f);
+/** Cancel a fiber. A cancelled fiber will have
+ * tnt_FiberCancelException raised in it.
+ *
+ * A fiber can be cancelled only if it is
+ * FIBER_CANCELLABLE flag is set.
+ */
 void fiber_cancel(struct fiber *f);
+/** Check if the current fiber has been cancelled.  Raises
+ * tnt_FiberCancelException
+ */
 void fiber_testcancel(void);
+/** Make it possible or not possible to cancel the current
+ * fiber.
+ */
 void fiber_setcancelstate(bool enable);
 int fiber_connect(struct sockaddr_in *addr);
 void fiber_sleep(ev_tstamp s);