From 5482dc61dec996a46842dcc02239eb8c1bc825d8 Mon Sep 17 00:00:00 2001 From: Roman Tsisyk <roman@tsisyk.com> Date: Fri, 19 Sep 2014 10:26:50 +0400 Subject: [PATCH] Fix #515: socket: excessively sparse array This patch adds __serialize hook to sockets to fix REPL && admin console. --- src/lua/bsdsocket.lua | 8 +++++++- test/box/bsdsocket.result | 29 ++++++++++++++++++++++++++++- test/box/bsdsocket.test.lua | 11 +++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/lua/bsdsocket.lua b/src/lua/bsdsocket.lua index a86e14bad8..871bdbd356 100644 --- a/src/lua/bsdsocket.lua +++ b/src/lua/bsdsocket.lua @@ -205,6 +205,7 @@ socket_methods.nonblock = function(self, nb) end end +local waiters_mt = { __serialize = 'mapping' } local function wait_safely(self, what, timeout) local fd = check_socket(self) local f = fiber.self() @@ -214,7 +215,7 @@ local function wait_safely(self, what, timeout) timeout = timeout or TIMEOUT_INFINITY if self.waiters == nil then - self.waiters = {} + self.waiters = setmetatable({}, waiters_mt) end self.waiters[fid] = true @@ -1072,6 +1073,11 @@ socket_mt = { end self._errno = save_errno return name + end, + __serialize = function(self) + -- Allow YAML, MsgPack and JSON to dump objects with sockets + local fd = check_socket(self) + return { fd = fd, peer = self:peer(), name = self:name() } end } diff --git a/test/box/bsdsocket.result b/test/box/bsdsocket.result index c803cb769e..ccc0973dea 100644 --- a/test/box/bsdsocket.result +++ b/test/box/bsdsocket.result @@ -1,6 +1,9 @@ json = require 'json' --- ... +yaml = require 'yaml' +--- +... pickle = require 'pickle' --- ... @@ -265,7 +268,7 @@ s:getsockopt('SOL_SOCKET', 'SO_DEBUG') ... s:setsockopt('SOL_SOCKET', 'SO_ACCEPTCONN', 1) --- -- error: 'builtin/socket.lua:340: Socket option SO_ACCEPTCONN is read only' +- error: 'builtin/socket.lua:341: Socket option SO_ACCEPTCONN is read only' ... s:getsockopt('SOL_SOCKET', 'SO_RCVBUF') > 32 --- @@ -1312,3 +1315,27 @@ os.remove(path) --- - true ... +-- Test serializers with sockets +s = socket('AF_UNIX', 'SOCK_STREAM', 'ip') +--- +... +x = s:wait() +--- +... +-- waiters is map +s.waiters +--- +- {} +... +-- check __serialize hook +json.decode(json.encode(s)).fd == s:fd() +--- +- true +... +yaml.decode(yaml.encode(s)).fd == s:fd() +--- +- true +... +s = nil +--- +... diff --git a/test/box/bsdsocket.test.lua b/test/box/bsdsocket.test.lua index 23d527bfbc..7ead955992 100644 --- a/test/box/bsdsocket.test.lua +++ b/test/box/bsdsocket.test.lua @@ -1,4 +1,5 @@ json = require 'json' +yaml = require 'yaml' pickle = require 'pickle' socket = require 'socket' fiber = require 'fiber' @@ -445,3 +446,13 @@ collectgarbage('collect') collectgarbage('collect') socket.tcp_connect('unix/', path), errno() == errno.ECONNREFUSED os.remove(path) + +-- Test serializers with sockets +s = socket('AF_UNIX', 'SOCK_STREAM', 'ip') +x = s:wait() +-- waiters is map +s.waiters +-- check __serialize hook +json.decode(json.encode(s)).fd == s:fd() +yaml.decode(yaml.encode(s)).fd == s:fd() +s = nil -- GitLab