* [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, ¬much_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).