Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)
pinned.c
Go to the documentation of this file.
1#include <fiddle.h>
2
5
6struct pinned_data {
8};
9
10static void
11pinned_mark(void *ptr)
12{
13 struct pinned_data *data = (struct pinned_data*)ptr;
14 /* Ensure reference is pinned */
15 if (data->ptr) {
16 rb_gc_mark(data->ptr);
17 }
18}
19
20static size_t
21pinned_memsize(const void *ptr)
22{
23 return sizeof(struct pinned_data);
24}
25
26static const rb_data_type_t pinned_data_type = {
27 "fiddle/pinned",
28 {pinned_mark, xfree, pinned_memsize, },
30};
31
32static VALUE
33allocate(VALUE klass)
34{
35 struct pinned_data *data;
36 VALUE obj = TypedData_Make_Struct(klass, struct pinned_data, &pinned_data_type, data);
37 data->ptr = 0;
38 return obj;
39}
40
41/*
42 * call-seq:
43 * Fiddle::Pinned.new(object) => pinned_object
44 *
45 * Create a new pinned object reference. The Fiddle::Pinned instance will
46 * prevent the GC from moving +object+.
47 */
48static VALUE
49initialize(VALUE self, VALUE ref)
50{
51 struct pinned_data *data;
52 TypedData_Get_Struct(self, struct pinned_data, &pinned_data_type, data);
53 RB_OBJ_WRITE(self, &data->ptr, ref);
54 return self;
55}
56
57/*
58 * call-seq: ref
59 *
60 * Return the object that this pinned instance references.
61 */
62static VALUE
63ref(VALUE self)
64{
65 struct pinned_data *data;
66 TypedData_Get_Struct(self, struct pinned_data, &pinned_data_type, data);
67 if (data->ptr) {
68 return data->ptr;
69 } else {
70 rb_raise(rb_eFiddleClearedReferenceError, "`ref` called on a cleared object");
71 }
72}
73
74/*
75 * call-seq: clear
76 *
77 * Clear the reference to the object this is pinning.
78 */
79static VALUE
80clear(VALUE self)
81{
82 struct pinned_data *data;
83 TypedData_Get_Struct(self, struct pinned_data, &pinned_data_type, data);
84 data->ptr = 0;
85 return self;
86}
87
88/*
89 * call-seq: cleared?
90 *
91 * Returns true if the reference has been cleared, otherwise returns false.
92 */
93static VALUE
94cleared_p(VALUE self)
95{
96 struct pinned_data *data;
97 TypedData_Get_Struct(self, struct pinned_data, &pinned_data_type, data);
98 if (data->ptr) {
99 return Qfalse;
100 } else {
101 return Qtrue;
102 }
103}
104
106
107void
109{
112 rb_define_method(rb_cPinned, "initialize", initialize, 1);
113 rb_define_method(rb_cPinned, "ref", ref, 0);
114 rb_define_method(rb_cPinned, "clear", clear, 0);
115 rb_define_method(rb_cPinned, "cleared?", cleared_p, 0);
116
117 /*
118 * Document-class: Fiddle::ClearedReferenceError
119 *
120 * Cleared reference exception
121 */
123}
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
Definition: cxxanyargs.hpp:653
struct RIMemo * ptr
Definition: debug.c:88
VALUE mFiddle
Definition: fiddle.c:3
void rb_gc_mark(VALUE ptr)
Definition: gc.c:6112
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:797
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2917
VALUE rb_cObject
Object class.
Definition: object.c:49
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_eFiddleClearedReferenceError
Definition: pinned.c:4
void Init_fiddle_pinned(void)
Definition: pinned.c:108
VALUE rb_eFiddleError
Definition: fiddle.c:5
VALUE rb_cPinned
Definition: pinned.c:3
#define RB_OBJ_WRITE(a, slot, b)
WB for new reference from ‘a’ to ‘b’.
Definition: rgengc.h:107
#define TypedData_Get_Struct(obj, type, data_type, sval)
Definition: rtypeddata.h:130
@ RUBY_TYPED_FREE_IMMEDIATELY
Definition: rtypeddata.h:62
@ RUBY_TYPED_WB_PROTECTED
Definition: rtypeddata.h:64
#define TypedData_Make_Struct(klass, type, data_type, sval)
Definition: rtypeddata.h:122
#define Qtrue
#define Qfalse
VALUE ptr
Definition: pinned.c:7
unsigned long VALUE
Definition: value.h:38
#define xfree
Definition: xmalloc.h:49