[grilo-plugins] lua-factory: Keep GrlNetWc saved as property



commit cdab2e7963688ac50e5ec5247dd4e843489f7eab
Author: Victor Toso <me victortoso com>
Date:   Sat Jul 30 16:39:00 2016 +0200

    lua-factory: Keep GrlNetWc saved as property
    
    In order to make usage of throttling from GrlNetWc we need to keep it
    stored to be used between different operation calls to the lua source.
    
    In order to store this pointer, we make usage of source table which is
    explained in 1074349f2f6ca3edc939313c7ff7d8ff2f5ae53b.
    The full path for this new table and the GrlNetWc userdata is
    * grl.__priv_state.properties
     - grl.__priv_state.properties.net_wc
    
    In order to avoid leaks from these properties, the priv_state has now
    a metattable with __gc set.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=769331

 src/lua-factory/grl-lua-common.h             |    2 +
 src/lua-factory/grl-lua-library-operations.c |  120 ++++++++++++++++++++++++++
 src/lua-factory/grl-lua-library-operations.h |    3 +
 3 files changed, 125 insertions(+), 0 deletions(-)
---
diff --git a/src/lua-factory/grl-lua-common.h b/src/lua-factory/grl-lua-common.h
index 92ef36e..eb70998 100644
--- a/src/lua-factory/grl-lua-common.h
+++ b/src/lua-factory/grl-lua-common.h
@@ -28,6 +28,7 @@
 
 #include "grl-lua-library.h"
 #include <glib/gi18n-lib.h>
+#include <net/grl-net.h>
 
 #ifdef GOA_ENABLED
 #define GOA_API_IS_SUBJECT_TO_CHANGE
@@ -99,5 +100,6 @@ void grl_lua_operations_set_source_state (lua_State *L, LuaSourceState state, Op
 void grl_lua_operations_cancel_operation (lua_State *L, guint operation_id);
 OperationSpec * grl_lua_operations_get_current_op (lua_State *L);
 gboolean grl_lua_operations_pcall (lua_State *L, gint nargs, OperationSpec *os, GError **err);
+GrlNetWc * grl_lua_operations_get_grl_net_wc (lua_State *L);
 
 #endif /* _GRL_LUA_LIBRARY_COMMON_H_ */
diff --git a/src/lua-factory/grl-lua-library-operations.c b/src/lua-factory/grl-lua-library-operations.c
index a58398b..fff9ef7 100644
--- a/src/lua-factory/grl-lua-library-operations.c
+++ b/src/lua-factory/grl-lua-library-operations.c
@@ -34,6 +34,7 @@ static const gchar * const source_op_state_str[LUA_SOURCE_NUM_STATES] = {
 };
 
 static OperationSpec * priv_state_current_op_get_op_data (lua_State *L);
+static void priv_state_properties_free (lua_State *L);
 
 /* =========================================================================
  * Internal functions ======================================================
@@ -121,6 +122,35 @@ proxy_metatable_handle_newindex (lua_State *L)
 /* ============== Private State helpers ==================================== */
 
 /*
+ * Should clear all data stored by us in private state table
+ */
+static int
+priv_state_metatable_gc (lua_State *L)
+{
+  priv_state_properties_free (L);
+  return 0;
+}
+
+/*
+ * Expects private state table in top of stack so it can set its metatable
+ */
+static void
+priv_state_set_metatable (lua_State *L)
+{
+  g_assert_true (lua_istable(L, -1));
+
+  /* create the metatable */
+  lua_createtable (L, 0, 1);
+  /* push the __gc key string */
+  lua_pushstring (L, "__gc");
+  /* push the __gc metamethod */
+  lua_pushcfunction (L, priv_state_metatable_gc);
+  /* set the __gc field in the metatable */
+  lua_settable (L, -3);
+  /* set table as the metatable of the userdata */
+  lua_setmetatable (L, -2);
+}
+/*
  * Helper function to let rw table from proxy in the top of stack
  */
 static void
@@ -451,6 +481,84 @@ priv_state_operations_update (lua_State *L,
   GRL_ERROR ("Ongoig operation not found (op-id: %d)", os->operation_id);
 }
 
+/* ============== Private State - Properties ================================ */
+
+/**
+ * priv_state_properties_new
+ *
+ * Creates a table of properties that this lua_State will hold for all
+ * operations that might happen.
+ *
+ * @L: LuaState of this GrlSource
+ *
+ * Leaves a new table in top of the stack
+ **/
+static void
+priv_state_properties_new (lua_State *L)
+{
+  GrlNetWc *wc;
+
+  lua_newtable (L);
+
+  wc = grl_net_wc_new ();
+  lua_pushstring (L, SOURCE_PROP_NET_WC);
+  lua_pushlightuserdata (L, wc);
+  lua_settable (L, -3);
+}
+
+/**
+ * priv_state_properties_free
+ *
+ * Free the data inside the properties table but don't destroy the table itself
+ * as garbage collection should handle that.
+ *
+ * @L: LuaState of this GrlSource
+ *
+ * Does not change the stack.
+ **/
+static void
+priv_state_properties_free (lua_State *L)
+{
+  GrlNetWc *wc;
+
+  priv_state_get_rw_table (L, LUA_SOURCE_PROPERTIES);
+
+  lua_getfield (L, -1, SOURCE_PROP_NET_WC);
+  g_assert_true (lua_islightuserdata (L, -1));
+  wc = lua_touserdata (L, -1);
+  g_object_unref (wc);
+
+  /* Keep the stack as it was before */
+  lua_pop (L, 2);
+}
+
+/**
+ * priv_state_properties_get_prop
+ *
+ * Get the property given by @prop_name.
+ *
+ * @L: LuaState of this GrlSource
+ * @prop_name: Property as gpointer
+ *
+ * Does not change the stack.
+ **/
+static gpointer
+priv_state_properties_get_prop (lua_State *L,
+                                const gchar *prop_name)
+{
+  gpointer property;
+
+  priv_state_get_rw_table (L, LUA_SOURCE_PROPERTIES);
+  lua_getfield (L, -1, prop_name);
+  /* FIXME: Should we consider all properties as userdata?
+   * https://bugzilla.gnome.org/show_bug.cgi?id=770794 */
+  property = lua_touserdata (L, -1);
+
+  /* Keep the stack as it was before */
+  lua_pop (L, 2);
+  return property;
+}
+
 /* ============== Watchdog related ========================================= */
 
 /**
@@ -607,10 +715,22 @@ grl_lua_operations_init_priv_state (lua_State *L)
   lua_pushnil (L);
   lua_settable (L, -3);
 
+  lua_pushstring (L, LUA_SOURCE_PROPERTIES);
+  priv_state_properties_new (L);
+  grl_lua_operations_set_proxy_table (L, -1);
+  lua_settable (L, -3);
+
+  priv_state_set_metatable (L);
   grl_lua_operations_set_proxy_table (L, -1);
   lua_settable (L, -3);
 }
 
+GrlNetWc *
+grl_lua_operations_get_grl_net_wc (lua_State *L)
+{
+  return priv_state_properties_get_prop (L, SOURCE_PROP_NET_WC);
+}
+
 /*
  * Create a read-only proxy table which will only be allowed to access the
  * original table.
diff --git a/src/lua-factory/grl-lua-library-operations.h b/src/lua-factory/grl-lua-library-operations.h
index f69bcd0..790373a 100644
--- a/src/lua-factory/grl-lua-library-operations.h
+++ b/src/lua-factory/grl-lua-library-operations.h
@@ -30,9 +30,12 @@
 #define LUA_SOURCE_PRIV_STATE "__priv_state"
 #define LUA_SOURCE_OPERATIONS "operations"
 #define LUA_SOURCE_CURRENT_OP "current_operation"
+#define LUA_SOURCE_PROPERTIES "properties"
 
 #define SOURCE_OP_STATE "state"
 #define SOURCE_OP_DATA  "data"
 #define SOURCE_OP_ID    "op_id"
 
+#define SOURCE_PROP_NET_WC "net_wc"
+
 #endif /* _GRL_LUA_LIBRARY_OPERATIONS_COMMON_H_ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]