]> git.sesse.net Git - nageru/commitdiff
Fix a memory leak in the Lua code.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 14 Nov 2015 16:40:14 +0000 (17:40 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 14 Nov 2015 16:40:14 +0000 (17:40 +0100)
theme.cpp

index bd1259062780ae0859b65b4042fdfa644785d745..f7ec8e8b8db32fcd4890c93b56b583e28d046e4c 100644 (file)
--- a/theme.cpp
+++ b/theme.cpp
@@ -20,6 +20,7 @@
 #include <cstddef>
 #include <new>
 #include <utility>
+#include <memory>
 
 #include "image_input.h"
 
@@ -37,6 +38,23 @@ namespace {
 
 vector<LiveInputWrapper *> live_inputs;
 
+class LuaRefWithDeleter {
+public:
+       LuaRefWithDeleter(mutex *m, lua_State *L, int ref) : m(m), L(L), ref(ref) {}
+       ~LuaRefWithDeleter() {
+               unique_lock<mutex> lock(*m);
+               luaL_unref(L, LUA_REGISTRYINDEX, ref);
+       }
+       int get() const { return ref; }
+
+private:
+       LuaRefWithDeleter(const LuaRefWithDeleter &) = delete;
+
+       mutex *m;
+       lua_State *L;
+       int ref;
+};
+
 template<class T, class... Args>
 int wrap_lua_object(lua_State* L, const char *class_name, Args&&... args)
 {
@@ -501,14 +519,14 @@ Theme::get_chain(unsigned num, float t, unsigned width, unsigned height)
                exit(1);
        }
        lua_pushvalue(L, -1);
-       int funcref = luaL_ref(L, LUA_REGISTRYINDEX);  // TODO: leak!
+       shared_ptr<LuaRefWithDeleter> funcref(new LuaRefWithDeleter(&m, L, luaL_ref(L, LUA_REGISTRYINDEX)));
        lua_pop(L, 2);
        assert(lua_gettop(L) == 0);
        return make_pair(chain, [this, funcref]{
                unique_lock<mutex> lock(m);
 
                // Set up state, including connecting signals.
-               lua_rawgeti(L, LUA_REGISTRYINDEX, funcref);
+               lua_rawgeti(L, LUA_REGISTRYINDEX, funcref->get());
                if (lua_pcall(L, 0, 0, 0) != 0) {
                        fprintf(stderr, "error running chain setup callback: %s\n", lua_tostring(L, -1));
                        exit(1);