From 318f85ac5f9a76d6cd081e76453f5351544fd4dc Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 31 May 2026 20:54:39 +0900 Subject: [PATCH] Refactor log settable module --- bindings/ruby/ext/ruby_whisper.c | 4 +- bindings/ruby/ext/ruby_whisper.h | 12 ++++ bindings/ruby/ext/ruby_whisper_log_settable.h | 47 +++++++++++++++ bindings/ruby/ext/ruby_whisper_parakeet.c | 58 +------------------ 4 files changed, 63 insertions(+), 58 deletions(-) create mode 100644 bindings/ruby/ext/ruby_whisper_log_settable.h diff --git a/bindings/ruby/ext/ruby_whisper.c b/bindings/ruby/ext/ruby_whisper.c index 70b637df6..627ecc523 100644 --- a/bindings/ruby/ext/ruby_whisper.c +++ b/bindings/ruby/ext/ruby_whisper.c @@ -40,7 +40,7 @@ ID id_n_processors; ID id_extended; ID id_start_log_callback_thread; ID id_log_callback_thread; -ID id_alive; +ID id_alive_p; ID id_join; static bool is_log_callback_finalized = false; @@ -208,7 +208,7 @@ void Init_whisper() { id_extended = rb_intern("extended"); id_start_log_callback_thread = rb_intern("start_log_callback_thread"); id_log_callback_thread = rb_intern("@log_callback_thread"); - id_alive = rb_intern("alive?"); + id_alive_p = rb_intern("alive?"); id_join = rb_intern("join"); mWhisper = rb_define_module("Whisper"); diff --git a/bindings/ruby/ext/ruby_whisper.h b/bindings/ruby/ext/ruby_whisper.h index faed71190..094f1fce9 100644 --- a/bindings/ruby/ext/ruby_whisper.h +++ b/bindings/ruby/ext/ruby_whisper.h @@ -10,6 +10,7 @@ #include #include "whisper.h" #include "parakeet.h" +#include "ruby_whisper_log_settable.h" #if RUBY_API_VERSION_MAJOR < 4 // Exists but not declared as public API @@ -148,6 +149,17 @@ typedef struct { VALUE context; } ruby_whisper_parakeet_model; +extern ID id_extended; +extern ID id_log_callback_thread; +extern ID id_start_log_callback_thread; +extern ID id_alive_p; +extern ID id_join; +extern void ruby_whisper_log_queue_initialize(ruby_whisper_log_queue *log_queue); +extern void ruby_whisper_log_queue_open(ruby_whisper_log_queue *log_queue); +extern void ruby_whisper_log_queue_close(ruby_whisper_log_queue *log_queue); +extern void ruby_whisper_log_queue_enqueue(ruby_whisper_log_queue *log_queue, enum ggml_log_level level, const char *text); +extern VALUE ruby_whisper_log_queue_drain(ruby_whisper_log_queue *log_queue); + #define GetContext(obj, rw) do { \ TypedData_Get_Struct((obj), ruby_whisper, &ruby_whisper_type, (rw)); \ if ((rw)->context == NULL) { \ diff --git a/bindings/ruby/ext/ruby_whisper_log_settable.h b/bindings/ruby/ext/ruby_whisper_log_settable.h new file mode 100644 index 000000000..b98fbac82 --- /dev/null +++ b/bindings/ruby/ext/ruby_whisper_log_settable.h @@ -0,0 +1,47 @@ +#ifndef RUBY_WHISPER_LOG_SETTABLE_H +#define RUBY_WHISPER_LOG_SETTABLE_H + +#define LOG_SETTABLE_SETUP(log_queue, mod, log_set) \ + static VALUE \ + ruby_whisper_##log_queue##_s_drain_logs(VALUE self) \ + { \ + return ruby_whisper_log_queue_drain(&log_queue); \ + } \ + static void \ + ruby_whisper_##log_queue##_log_callback(enum ggml_log_level level, const char *text, void *user_data) \ + { \ + ruby_whisper_log_queue_enqueue(&log_queue, level, text); \ + } \ + static VALUE \ + ruby_whisper_##log_queue##_s_log_set(VALUE self, VALUE log_callback, VALUE user_data) \ + { \ + rb_iv_set(self, "@log_callback", log_callback); \ + rb_iv_set(self, "@log_callback_user_data", user_data); \ + if (NIL_P(log_callback)) { \ + log_set(NULL, NULL); \ + } else { \ + ruby_whisper_log_queue_open(&log_queue); \ + rb_funcall((mod), id_start_log_callback_thread, 0); \ + log_set(ruby_whisper_##log_queue##_log_callback, NULL); \ + } \ + return Qnil; \ + } \ + static void \ + ruby_whisper_##log_queue##_end_proc(VALUE args) \ + { \ + ruby_whisper_log_queue_close(&log_queue); \ + VALUE log_callback_thread = rb_ivar_get(mod, id_log_callback_thread); \ + if (!NIL_P(log_callback_thread) && RTEST(rb_funcall(log_callback_thread, id_alive_p, 0))) { \ + rb_funcall(log_callback_thread, id_join, 0); \ + } \ + } + +#define LOG_SETTABLE_INIT(log_queue, mod) \ + ruby_whisper_log_queue_initialize(&log_queue); \ + rb_define_singleton_method(mod, "drain_logs", ruby_whisper_##log_queue##_s_drain_logs, 0); \ + rb_define_singleton_method(mod, "log_set", ruby_whisper_##log_queue##_s_log_set, 2); \ + rb_set_end_proc(ruby_whisper_##log_queue##_end_proc, Qnil); \ + rb_extend_object(mod, mLogSettable); \ + rb_funcall(mLogSettable, id_extended, 1, mod); + +#endif diff --git a/bindings/ruby/ext/ruby_whisper_parakeet.c b/bindings/ruby/ext/ruby_whisper_parakeet.c index 6d31cee62..d69369401 100644 --- a/bindings/ruby/ext/ruby_whisper_parakeet.c +++ b/bindings/ruby/ext/ruby_whisper_parakeet.c @@ -8,11 +8,6 @@ extern VALUE cParakeetContext; extern VALUE cParakeetSegment; extern VALUE mOutputContext; extern VALUE mOutputSegment; -extern ID id_extended; -extern ID id_log_callback_thread; -extern ID id_start_log_callback_thread; -extern ID id_alive; -extern ID id_join; extern void init_ruby_whisper_parakeet_params(VALUE *mParakeet); extern void init_ruby_whisper_parakeet_token(VALUE *mParakeet); @@ -21,41 +16,9 @@ extern VALUE init_ruby_whisper_parakeet_context(VALUE *mParakeet); extern void init_ruby_whisper_parakeet_context_params(VALUE *cParakeetContext); extern void init_ruby_whisper_parakeet_model(VALUE *mParakeet); -extern void ruby_whisper_log_queue_initialize(ruby_whisper_log_queue *log_queue); -extern void ruby_whisper_log_queue_open(ruby_whisper_log_queue *log_queue); -extern void ruby_whisper_log_queue_close(ruby_whisper_log_queue *log_queue); -extern void ruby_whisper_log_queue_enqueue(ruby_whisper_log_queue *log_queue, enum ggml_log_level level, const char *text); -extern VALUE ruby_whisper_log_queue_drain(ruby_whisper_log_queue *log_queue); - static ruby_whisper_log_queue parakeet_log_queue; -static VALUE -ruby_whisper_parakeet_s_drain_logs(VALUE self) -{ - return ruby_whisper_log_queue_drain(¶keet_log_queue); -} - -static void -ruby_whisper_parakeet_log_callback(enum ggml_log_level level, const char *text, void *user_data) -{ - ruby_whisper_log_queue_enqueue(¶keet_log_queue, level, text); -} - -static VALUE -ruby_whisper_parakeet_s_log_set(VALUE self, VALUE log_callback, VALUE user_data) -{ - rb_iv_set(self, "@log_callback", log_callback); - rb_iv_set(self, "@log_callback_user_data", user_data); - if (NIL_P(log_callback)) { - parakeet_log_set(NULL, NULL); - } else { - ruby_whisper_log_queue_open(¶keet_log_queue); - rb_funcall(mParakeet, id_start_log_callback_thread, 0); - parakeet_log_set(ruby_whisper_parakeet_log_callback, NULL); - } - - return Qnil; -} +LOG_SETTABLE_SETUP(parakeet_log_queue, mParakeet, parakeet_log_set) static VALUE ruby_whisper_parakeet_s_system_info_str(VALUE self) @@ -63,17 +26,6 @@ ruby_whisper_parakeet_s_system_info_str(VALUE self) return rb_str_new2(parakeet_print_system_info()); } -static void -ruby_whisper_parakeet_end_proc(VALUE args) -{ - ruby_whisper_log_queue_close(¶keet_log_queue); - - VALUE log_callback_thread = rb_ivar_get(mParakeet, id_log_callback_thread); - if (!NIL_P(log_callback_thread) && RTEST(rb_funcall(log_callback_thread, id_alive, 0))) { - rb_funcall(log_callback_thread, id_join, 0); - } -} - void init_ruby_whisper_parakeet(VALUE *mWhisper) { @@ -81,15 +33,9 @@ init_ruby_whisper_parakeet(VALUE *mWhisper) rb_define_const(mParakeet, "VERSION", rb_str_new2(parakeet_version())); - ruby_whisper_log_queue_initialize(¶keet_log_queue); + LOG_SETTABLE_INIT(parakeet_log_queue, mParakeet) - rb_define_singleton_method(mParakeet, "log_set", ruby_whisper_parakeet_s_log_set, 2); rb_define_singleton_method(mParakeet, "system_info_str", ruby_whisper_parakeet_s_system_info_str, 0); - rb_define_private_method(rb_singleton_class(mParakeet), "drain_logs", ruby_whisper_parakeet_s_drain_logs, 0); - - rb_set_end_proc(ruby_whisper_parakeet_end_proc, Qnil); - rb_extend_object(mParakeet, mLogSettable); - rb_funcall(mLogSettable, id_extended, 1, mParakeet); init_ruby_whisper_parakeet_params(&mParakeet); init_ruby_whisper_parakeet_token(&mParakeet);