Skip to content

Commit

Permalink
Merge pull request #466 from byroot/fix-busy-handler-compaction
Browse files Browse the repository at this point in the history
Fix a GC compaction issue with `busy_handler`
  • Loading branch information
tenderlove committed Jan 9, 2024
2 parents 5361528 + e46e1d2 commit dfa2c8b
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 14 deletions.
36 changes: 22 additions & 14 deletions ext/sqlite3/database.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@

VALUE cSqlite3Database;

static void
database_mark(void *ctx)
{
sqlite3RubyPtr c = (sqlite3RubyPtr)ctx;
rb_gc_mark(c->busy_handler);
}

static void
deallocate(void *ctx)
{
Expand All @@ -31,15 +38,13 @@ database_memsize(const void *ctx)
}

static const rb_data_type_t database_type = {
"SQLite3::Backup",
{
NULL,
deallocate,
database_memsize,
.wrap_struct_name = "SQLite3::Backup",
.function = {
.dmark = database_mark,
.dfree = deallocate,
.dsize = database_memsize,
},
0,
0,
RUBY_TYPED_WB_PROTECTED, // Not freed immediately because the dfree function do IOs.
.flags = RUBY_TYPED_WB_PROTECTED, // Not freed immediately because the dfree function do IOs.
};

static VALUE
Expand Down Expand Up @@ -202,10 +207,11 @@ trace(int argc, VALUE *argv, VALUE self)
}

static int
rb_sqlite3_busy_handler(void *ctx, int count)
rb_sqlite3_busy_handler(void *context, int count)
{
VALUE self = (VALUE)(ctx);
VALUE handle = rb_iv_get(self, "@busy_handler");
sqlite3RubyPtr ctx = (sqlite3RubyPtr)context;

VALUE handle = ctx->busy_handler;
VALUE result = rb_funcall(handle, rb_intern("call"), 1, INT2NUM(count));

if (Qfalse == result) { return 0; }
Expand Down Expand Up @@ -240,11 +246,13 @@ busy_handler(int argc, VALUE *argv, VALUE self)
rb_scan_args(argc, argv, "01", &block);

if (NIL_P(block) && rb_block_given_p()) { block = rb_block_proc(); }

rb_iv_set(self, "@busy_handler", block);
ctx->busy_handler = block;

status = sqlite3_busy_handler(
ctx->db, NIL_P(block) ? NULL : rb_sqlite3_busy_handler, (void *)self);
ctx->db,
NIL_P(block) ? NULL : rb_sqlite3_busy_handler,
(void *)ctx
);

CHECK(ctx->db, status);

Expand Down
1 change: 1 addition & 0 deletions ext/sqlite3/database.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

struct _sqlite3Ruby {
sqlite3 *db;
VALUE busy_handler;
};

typedef struct _sqlite3Ruby sqlite3Ruby;
Expand Down

0 comments on commit dfa2c8b

Please sign in to comment.