Skip to content

Commit

Permalink
ffi: use a new C library namespace when the dynamic library load
Browse files Browse the repository at this point in the history
If symbols from the dynamic library are loaded into the
global namespace (ffi.C), by invoke ffi.load() with global
is true and without save the return value, it may be
garbage collected. For correct work the return value
must be saved.
Example - tarantool/tarantool#4999
So, use a new C library namespace instead the global one.
This will help to keep the global namespace clean and
avoid the problem with garbage collection.
  • Loading branch information
LeonidVas authored and Totktonada committed Jun 1, 2020
1 parent 8401d47 commit 62a557f
Showing 1 changed file with 11 additions and 9 deletions.
20 changes: 11 additions & 9 deletions memcached/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ local fmt = string.format

local internal_so_path = package.search('memcached.internal')
assert(internal_so_path, "Failed to find memcached/internal.so library")
ffi.load(internal_so_path, true)
local memcached_internal = ffi.load(internal_so_path)

ffi.cdef[[
struct memcached_stat {
Expand Down Expand Up @@ -267,7 +267,8 @@ local memcached_methods = {
end
for k, v in pairs(opts) do
if conf_table[k] ~= nil then
C.memcached_set_opt(self.service, conf_table[k], v)
memcached_internal.memcached_set_opt(self.service,
conf_table[k], v)
self.opts[k] = v
end
end
Expand All @@ -276,14 +277,14 @@ local memcached_methods = {
start = function (self)
local function memcached_handler(socket, addr)
log.debug('client %s:%s connected', addr.host, addr.port)
C.memcached_handler(self.service, socket:fd())
memcached_internal.memcached_handler(self.service, socket:fd())
end
jit.off(memcached_handler)

if self.status == RUNNING then
error(fmt(err_is_started, self.name))
end
C.memcached_start(self.service)
memcached_internal.memcached_start(self.service)
local parsed = uri.parse(self.uri)
self.listener = socket.tcp_server(parsed.host, parsed.service, {
handler = memcached_handler
Expand All @@ -293,7 +294,7 @@ local memcached_methods = {
self.status = ERRORED
error(fmt('can\'t bind (%d) %s', errno(), errno.strerror()))
end
if (C.memcached_setsockopt(self.listener:fd(),
if (memcached_internal.memcached_setsockopt(self.listener:fd(),
lname.family,
lname.type) == -1) then
self.status = ERRORED
Expand All @@ -309,12 +310,12 @@ local memcached_methods = {
if (self.listener ~= nil) then
self.listener:close()
end
local rc = C.memcached_stop(self.service)
local rc = memcached_internal.memcached_stop(self.service)
self.status = STOPPED
return self
end,
info = function (self)
local stats = C.memcached_get_stat(self.service)
local stats = memcached_internal.memcached_get_stat(self.service)
local retval = {}
for k, v in pairs(stat_table) do
retval[v] = stats[0][v]
Expand Down Expand Up @@ -362,11 +363,12 @@ local function memcached_init(name, uri, opts)
else
instance.space = box.space[instance.space_name]
end
local service = C.memcached_create(instance.name, instance.space.id)
local service = memcached_internal.memcached_create(instance.name,
instance.space.id)
if service == nil then
error(fmt(err_enomem, "memcached service"))
end
instance.service = ffi.gc(service, C.memcached_free)
instance.service = ffi.gc(service, memcached_internal.memcached_free)
memcached_services[instance.name] = setmetatable(instance, {
__index = memcached_methods
})
Expand Down

0 comments on commit 62a557f

Please sign in to comment.