about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--ext/raindrops/linux_inet_diag.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/ext/raindrops/linux_inet_diag.c b/ext/raindrops/linux_inet_diag.c
index e4d0fab..773e094 100644
--- a/ext/raindrops/linux_inet_diag.c
+++ b/ext/raindrops/linux_inet_diag.c
@@ -465,12 +465,12 @@ static VALUE diag(void *ptr)
                 }
         }
 out:
-        {
+        /* prepare to raise, free memory before reacquiring GVL */
+        if (err && args->table) {
                 int save_errno = errno;
-                if (err && args->table) {
-                        st_foreach(args->table, st_free_data, 0);
-                        st_free_table(args->table);
-                }
+
+                st_foreach(args->table, st_free_data, 0);
+                st_free_table(args->table);
                 errno = save_errno;
         }
         return (VALUE)err;
@@ -584,6 +584,10 @@ static void gen_bytecode(struct iovec *iov, union any_addr *inet)
         }
 }
 
+/*
+ * n.b. we may safely raise here because an error will cause diag()
+ * to free args->table
+ */
 static void nl_errcheck(VALUE r)
 {
         const char *err = (const char *)r;