Implement GC handler to release broker reference properly.
authorGuo Rui <firemeteor@Adam.(none)>
Mon, 27 Jul 2009 16:18:06 +0000 (28 00:18 +0800)
committerGuo Rui <firemeteor@Adam.(none)>
Mon, 27 Jul 2009 16:18:06 +0000 (28 00:18 +0800)
src/lua.c
src/script.c
src/script.h

index 365d884..09dc95e 100644 (file)
--- a/src/lua.c
+++ b/src/lua.c
@@ -404,6 +404,16 @@ static const struct Xet_reg callback_getters[] = {
 
 /** }}} */
 
+static int
+screen_object_collect(lua_State *L)
+{
+  struct broker **pbroker;
+  luaL_checktype(L, 1, LUA_TUSERDATA);
+  pbroker = (struct broker **)lua_touserdata(L, 1);
+  broker_unref(pbroker);
+  return 0;
+}
+
 /** Window {{{ */
 
 PUSH_TYPE(window, struct win)
@@ -502,6 +512,7 @@ window_equality(lua_State *L)
 static const luaL_reg window_metamethods[] = {
   {"__tostring", window_tostring},
   {"__eq", window_equality},
+  {"__gc", screen_object_collect},
   {0, 0}
 };
 
@@ -554,6 +565,7 @@ user_tostring(lua_State *L)
 
 static const luaL_reg user_metamethods[] = {
   {"__tostring", user_tostring},
+  {"__gc", screen_object_collect},
   {0, 0}
 };
 
@@ -631,6 +643,7 @@ static const luaL_reg canvas_methods[] = {
 };
 
 static const luaL_reg canvas_metamethods[] = {
+  {"__gc", screen_object_collect},
   {0, 0}
 };
 
@@ -751,6 +764,11 @@ static const luaL_reg layout_methods[] = {
   {0, 0}
 };
 
+static const luaL_reg layout_metamethods[] = {
+  {"__gc", screen_object_collect},
+  {0, 0}
+};
+
 static int
 get_layout(lua_State *L, void *v)
 {
@@ -834,6 +852,7 @@ display_tostring(lua_State *L)
 
 static const luaL_reg display_metamethods[] = {
   {"__tostring", display_tostring},
+  {"__gc", screen_object_collect},
   {0, 0}
 };
 
index 2717a97..10203ad 100644 (file)
@@ -377,6 +377,20 @@ void * get_broker_obj(struct broker **pbroker)
     return broker->obj;
 
   /* Clear the invalid reference, and decrease the ref-count. */
+  broker_unref(pbroker);
+  return NULL;
+}
+
+void broker_inv_obj(void *obj)
+{
+  struct broker **b = broker_from_obj(obj);
+  if (*b)
+    (*b)->valid = 0;
+}
+
+void broker_unref(struct broker **pbroker)
+{
+  struct broker *broker = *pbroker;
   *pbroker = NULL;
   if (--broker->ref == 0)
     {
@@ -386,16 +400,8 @@ void * get_broker_obj(struct broker **pbroker)
          free(*b);
          *b = n;
       } else {
-         /* Should not happen!*/
+         /* FIXME:Should not happen! But act better.*/
+         exit(1);
       }
     }
-  return NULL;
-}
-
-void broker_inv_obj(void *obj)
-{
-  struct broker **b = broker_from_obj(obj);
-  if (*b)
-    (*b)->valid = 0;
 }
-
index 5f9a1e4..ec47f42 100644 (file)
@@ -93,6 +93,7 @@ struct broker
 struct broker *get_obj_broker(void *obj);
 void * get_broker_obj(struct broker **pbroker);
 void broker_inv_obj(void *obj);
+void broker_unref(struct broker **pbroker);
 
 struct gevents
 {