From 7c76ad19ef664f1e744657eca93c8ce5498a7b9b Mon Sep 17 00:00:00 2001
From: Konstantin Osipov <kostja@tarantool.org>
Date: Thu, 10 Apr 2014 22:04:09 +0400
Subject: [PATCH] [gh-229] Read line in a separate thread.

Don't block the event loop in the interactive mode.
Fix a merge bug (remove a debug print out from the test system).
---
 src/ffisyms.cc               |  3 ---
 src/lua/init.cc              | 36 +++++++++++++++++++++++++++---------
 src/lua/init.h               |  2 +-
 src/lua/interactive.lua      | 12 ++----------
 test/lib/tarantool_server.py |  3 ---
 5 files changed, 30 insertions(+), 26 deletions(-)

diff --git a/src/ffisyms.cc b/src/ffisyms.cc
index f6a0ba5218..b8e6dbe926 100644
--- a/src/ffisyms.cc
+++ b/src/ffisyms.cc
@@ -7,8 +7,6 @@
 #include <box/lua/call.h>
 #include <lua/init.h>
 #include <tarantool.h>
-#include <stdio.h>
-#include <readline/readline.h>
 
 /*
  * A special hack to cc/ld to keep symbols in an optimized binary.
@@ -31,7 +29,6 @@ void *ffi_symbols[] = {
 	(void *) port_ffi_destroy,
 	(void *) boxffi_select,
 	(void *) password_prepare,
-	(void *) readline,
 	(void *) tarantool_lua_interactive,
 	(void *) load_cfg,
 	(void *) box_set_wal_fsync_delay,
diff --git a/src/lua/init.cc b/src/lua/init.cc
index e2a8076cdb..6c9194265a 100644
--- a/src/lua/init.cc
+++ b/src/lua/init.cc
@@ -44,6 +44,7 @@ extern "C" {
 
 
 #include <fiber.h>
+#include "coeio.h"
 #include "lua/fiber.h"
 #include "lua/admin.h"
 #include "lua/errinj.h"
@@ -58,6 +59,8 @@ extern "C" {
 
 #include <ctype.h>
 #include "small/region.h"
+#include <stdio.h>
+#include <readline/readline.h>
 #include <readline/history.h>
 
 struct lua_State *tarantool_L;
@@ -422,17 +425,32 @@ tarantool_lua(struct lua_State *L,
 
 char *history = NULL;
 
+ssize_t
+readline_cb(va_list ap)
+{
+	const char **line = va_arg(ap, const char **);
+	*line = readline("tarantool> ");
+	return 0;
+}
+
 extern "C" void
-tarantool_lua_interactive(char *line)
+tarantool_lua_interactive()
 {
-	struct tbuf *out = tbuf_new(&fiber()->gc);
-	struct lua_State *L = lua_newthread(tarantool_L);
-	tarantool_lua(L, out, line);
-	lua_pop(tarantool_L, 1);
-	printf("%.*s", out->size, out->data);
-	fiber_gc();
-	if (history)
-		add_history(line);
+	char *line;
+	while (true) {
+		coeio_custom(readline_cb, TIMEOUT_INFINITY, &line);
+		if (line == NULL)
+			break;
+		struct tbuf *out = tbuf_new(&fiber()->gc);
+		struct lua_State *L = lua_newthread(tarantool_L);
+		tarantool_lua(L, out, line);
+		lua_pop(tarantool_L, 1);
+		printf("%.*s", out->size, out->data);
+		fiber_gc();
+		if (history)
+			add_history(line);
+		free(line);
+	}
 }
 
 /**
diff --git a/src/lua/init.h b/src/lua/init.h
index 34529787d9..2b97ff1f6c 100644
--- a/src/lua/init.h
+++ b/src/lua/init.h
@@ -85,6 +85,6 @@ extern char *history;
  * Eval line and print output.
  */
 extern "C" void
-tarantool_lua_interactive(char *line);
+tarantool_lua_interactive();
 
 #endif /* INCLUDES_TARANTOOL_LUA_H */
diff --git a/src/lua/interactive.lua b/src/lua/interactive.lua
index 3ca5a37e05..f9aea57bbf 100644
--- a/src/lua/interactive.lua
+++ b/src/lua/interactive.lua
@@ -2,20 +2,12 @@
 --
 local ffi = require('ffi')
 ffi.cdef([[
-    char *readline(const char *prompt);
-    void tarantool_lua_interactive(char *);
+    void tarantool_lua_interactive();
     void free(void *ptr);
 ]])
 
 function interactive()
-    while true do
-        line = ffi.C.readline("tarantool> ")
-        if line == nil then
-            return
-        end
-        ffi.C.tarantool_lua_interactive(line)
-        ffi.C.free(line)
-    end
+        ffi.C.tarantool_lua_interactive()
 end
 
 jit.off(interactive)
diff --git a/test/lib/tarantool_server.py b/test/lib/tarantool_server.py
index 004cff8b5d..6d03fe0e91 100644
--- a/test/lib/tarantool_server.py
+++ b/test/lib/tarantool_server.py
@@ -502,9 +502,6 @@ class TarantoolServer(Server):
         2) wait until server tells us his status
 
         """
-        print self.logfile_pos.log_begin
-        print self.logfile_pos.path
-
         self.logfile_pos.seek_from('entering the event loop', self.process if not self.gdb else None)
         while True:
             try:
-- 
GitLab