unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [RFC PATCH] Attempt to reactive Ruby gc
@ 2021-04-27  8:53 Felipe Contreras
  0 siblings, 0 replies; only message in thread
From: Felipe Contreras @ 2021-04-27  8:53 UTC (permalink / raw)
  To: notmuch; +Cc: Ali Polatel

Commit c7893408 (ruby: Kill garbage collection related cruft.,
2010-05-26) removed garbage collection because the order of objects
freed couldn't be ensured in Ruby.

However, we can use talloc for reference counting and thus preventing
Ruby from destroying the objects.

First we create a wrapper object with no talloc parent, which will be
owned by the Ruby object (e.g. Notmuch::Thread). The notmuch object
(notmuch_thread_t) will have two parents then (notmuch_threads_t and
Notmuch::Thread).

If Ruby destroys the other parent first (notmuch_threads_t), that still
doesn't destroy the object, since we still own a reference (from
Notmuch::Thread).

It's only when both are destroyed that the object is actually freed.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 bindings/ruby/defs.h     | 24 +++++++++++++++++++++++-
 bindings/ruby/extconf.rb |  1 +
 bindings/ruby/thread.c   |  6 +++---
 bindings/ruby/threads.c  |  2 +-
 4 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/bindings/ruby/defs.h b/bindings/ruby/defs.h
index 48544ca2..56a70a4f 100644
--- a/bindings/ruby/defs.h
+++ b/bindings/ruby/defs.h
@@ -23,6 +23,7 @@
 
 #include <notmuch.h>
 #include <ruby.h>
+#include <talloc.h>
 
 extern VALUE notmuch_rb_cDatabase;
 extern VALUE notmuch_rb_cDirectory;
@@ -50,6 +51,25 @@ extern ID ID_call;
 extern ID ID_db_create;
 extern ID ID_db_mode;
 
+typedef struct {
+    void *pointer;
+} notmuch_rb_object_t;
+
+static inline void
+notmuch_rb_object_free (void *object)
+{
+    talloc_free (object);
+}
+
+static inline VALUE
+notmuch_rb_object_wrap (VALUE klass, void *ptr)
+{
+    notmuch_rb_object_t *object = talloc (NULL, typeof (*object));
+    object->pointer = ptr;
+    talloc_reference (object, ptr);
+    return Data_Wrap_Struct (klass, NULL, &notmuch_rb_object_free, object);
+}
+
 /* RSTRING_PTR() is new in ruby-1.9 */
 #if !defined(RSTRING_PTR)
 # define RSTRING_PTR(v) (RSTRING((v))->ptr)
@@ -105,10 +125,12 @@ extern ID ID_db_mode;
 
 #define Data_Get_Notmuch_Thread(obj, ptr)			\
     do {							\
+	notmuch_rb_object_t *object;				\
 	Check_Type ((obj), T_DATA);				\
 	if (DATA_PTR ((obj)) == NULL)				\
 	rb_raise (rb_eRuntimeError, "thread destroyed");	\
-	Data_Get_Struct ((obj), notmuch_thread_t, (ptr));	\
+	Data_Get_Struct ((obj), typeof (*object), object);	\
+	(ptr) = object->pointer;					\
     } while (0)
 
 #define Data_Get_Notmuch_Message(obj, ptr)			\
diff --git a/bindings/ruby/extconf.rb b/bindings/ruby/extconf.rb
index 161de5a2..d914537c 100644
--- a/bindings/ruby/extconf.rb
+++ b/bindings/ruby/extconf.rb
@@ -19,6 +19,7 @@ if not ENV['LIBNOTMUCH']
 end
 
 $LOCAL_LIBS += ENV['LIBNOTMUCH']
+$LIBS += " -ltalloc"
 
 # Create Makefile
 dir_config('notmuch')
diff --git a/bindings/ruby/thread.c b/bindings/ruby/thread.c
index 9b295981..5705b556 100644
--- a/bindings/ruby/thread.c
+++ b/bindings/ruby/thread.c
@@ -28,11 +28,11 @@
 VALUE
 notmuch_rb_thread_destroy (VALUE self)
 {
-    notmuch_thread_t *thread;
+    notmuch_rb_object_t *object;
 
-    Data_Get_Notmuch_Thread (self, thread);
+    Data_Get_Struct (self, typeof (*object), object);
 
-    notmuch_thread_destroy (thread);
+    notmuch_rb_object_free (object);
     DATA_PTR (self) = NULL;
 
     return Qnil;
diff --git a/bindings/ruby/threads.c b/bindings/ruby/threads.c
index ed403a8f..302ffd91 100644
--- a/bindings/ruby/threads.c
+++ b/bindings/ruby/threads.c
@@ -53,7 +53,7 @@ notmuch_rb_threads_each (VALUE self)
 
     for (; notmuch_threads_valid (threads); notmuch_threads_move_to_next (threads)) {
 	thread = notmuch_threads_get (threads);
-	rb_yield (Data_Wrap_Struct (notmuch_rb_cThread, NULL, NULL, thread));
+	rb_yield (notmuch_rb_object_wrap (notmuch_rb_cThread, thread));
     }
 
     return self;
-- 
2.31.0

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2021-04-27  8:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-27  8:53 [RFC PATCH] Attempt to reactive Ruby gc Felipe Contreras

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).