Skip to content

Commit 2ad9384

Browse files
authored
Use typed data APIs (#85)
1 parent 489ec55 commit 2ad9384

File tree

8 files changed

+109
-72
lines changed

8 files changed

+109
-72
lines changed

ext/cool.io/buffer.c

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ static VALUE mCoolio = Qnil;
4747
static VALUE cCoolio_Buffer = Qnil;
4848

4949
static VALUE Coolio_Buffer_allocate(VALUE klass);
50-
static void Coolio_Buffer_mark(struct buffer *);
51-
static void Coolio_Buffer_free(struct buffer *);
50+
static void Coolio_Buffer_mark(void *);
51+
static void Coolio_Buffer_free(void *);
5252

5353
static VALUE Coolio_Buffer_default_node_size(VALUE klass);
5454
static VALUE Coolio_Buffer_set_default_node_size(VALUE klass, VALUE size);
@@ -64,7 +64,7 @@ static VALUE Coolio_Buffer_to_str(VALUE self);
6464
static VALUE Coolio_Buffer_read_from(VALUE self, VALUE io);
6565
static VALUE Coolio_Buffer_write_to(VALUE self, VALUE io);
6666

67-
static struct buffer *buffer_new(void);
67+
static struct buffer *buffer_init(struct buffer *);
6868
static void buffer_clear(struct buffer * buf);
6969
static void buffer_free(struct buffer * buf);
7070
static void buffer_free_pool(struct buffer * buf);
@@ -86,8 +86,6 @@ static int buffer_write_to(struct buffer * buf, int fd);
8686
void
8787
Init_coolio_buffer()
8888
{
89-
VALUE cCoolio_IO;
90-
9189
mCoolio = rb_define_module("Coolio");
9290
cCoolio_Buffer = rb_define_class_under(mCoolio, "Buffer", rb_cObject);
9391
rb_define_alloc_func(cCoolio_Buffer, Coolio_Buffer_allocate);
@@ -114,21 +112,33 @@ Init_coolio_buffer()
114112
rb_define_const(cCoolio_Buffer, "MAX_SIZE", INT2NUM(MAX_BUFFER_SIZE));
115113
}
116114

115+
static const rb_data_type_t Coolio_Buffer_type = {
116+
"Coolio::Buffer",
117+
{
118+
Coolio_Buffer_mark,
119+
Coolio_Buffer_free,
120+
}
121+
};
122+
117123
static VALUE
118124
Coolio_Buffer_allocate(VALUE klass)
119125
{
120-
return Data_Wrap_Struct(klass, Coolio_Buffer_mark, Coolio_Buffer_free, buffer_new());
126+
struct buffer *buf;
127+
VALUE buffer = TypedData_Make_Struct(klass, struct buffer, &Coolio_Buffer_type, buf);
128+
129+
buffer_init(buf);
130+
return buffer;
121131
}
122132

123133
static void
124-
Coolio_Buffer_mark(struct buffer * buf)
134+
Coolio_Buffer_mark(void *buf)
125135
{
126136
/* Naively discard the memory pool whenever Ruby garbage collects */
127137
buffer_free_pool(buf);
128138
}
129139

130140
static void
131-
Coolio_Buffer_free(struct buffer * buf)
141+
Coolio_Buffer_free(void * buf)
132142
{
133143
buffer_free(buf);
134144
}
@@ -188,7 +198,7 @@ Coolio_Buffer_initialize(int argc, VALUE * argv, VALUE self)
188198
struct buffer *buf;
189199

190200
if (rb_scan_args(argc, argv, "01", &node_size_obj) == 1) {
191-
Data_Get_Struct(self, struct buffer, buf);
201+
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);
192202

193203
/*
194204
* Make sure we're not changing the buffer size after data
@@ -212,7 +222,7 @@ static VALUE
212222
Coolio_Buffer_clear(VALUE self)
213223
{
214224
struct buffer *buf;
215-
Data_Get_Struct(self, struct buffer, buf);
225+
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);
216226

217227
buffer_clear(buf);
218228

@@ -229,7 +239,7 @@ static VALUE
229239
Coolio_Buffer_size(VALUE self)
230240
{
231241
struct buffer *buf;
232-
Data_Get_Struct(self, struct buffer, buf);
242+
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);
233243

234244
return INT2NUM(buf->size);
235245
}
@@ -244,7 +254,7 @@ static VALUE
244254
Coolio_Buffer_empty(VALUE self)
245255
{
246256
struct buffer *buf;
247-
Data_Get_Struct(self, struct buffer, buf);
257+
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);
248258

249259
return buf->size > 0 ? Qfalse : Qtrue;
250260
}
@@ -259,7 +269,7 @@ static VALUE
259269
Coolio_Buffer_append(VALUE self, VALUE data)
260270
{
261271
struct buffer *buf;
262-
Data_Get_Struct(self, struct buffer, buf);
272+
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);
263273

264274
/* Is this needed? Never seen anyone else do it... */
265275
data = rb_convert_type(data, T_STRING, "String", "to_str");
@@ -278,7 +288,7 @@ static VALUE
278288
Coolio_Buffer_prepend(VALUE self, VALUE data)
279289
{
280290
struct buffer *buf;
281-
Data_Get_Struct(self, struct buffer, buf);
291+
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);
282292

283293
data = rb_convert_type(data, T_STRING, "String", "to_str");
284294
buffer_prepend(buf, RSTRING_PTR(data), RSTRING_LEN(data));
@@ -304,7 +314,7 @@ Coolio_Buffer_read(int argc, VALUE * argv, VALUE self)
304314
int length;
305315
struct buffer *buf;
306316

307-
Data_Get_Struct(self, struct buffer, buf);
317+
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);
308318

309319
if (rb_scan_args(argc, argv, "01", &length_obj) == 1) {
310320
length = NUM2INT(length_obj);
@@ -340,7 +350,7 @@ Coolio_Buffer_read_frame(VALUE self, VALUE data, VALUE mark)
340350
char mark_c = (char) NUM2INT(mark);
341351
struct buffer *buf;
342352

343-
Data_Get_Struct(self, struct buffer, buf);
353+
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);
344354

345355
if (buffer_read_frame(buf, data, mark_c)) {
346356
return Qtrue;
@@ -361,7 +371,7 @@ Coolio_Buffer_to_str(VALUE self)
361371
VALUE str;
362372
struct buffer *buf;
363373

364-
Data_Get_Struct(self, struct buffer, buf);
374+
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);
365375

366376
str = rb_str_new(0, buf->size);
367377
buffer_copy(buf, RSTRING_PTR(str), buf->size);
@@ -388,7 +398,7 @@ Coolio_Buffer_read_from(VALUE self, VALUE io)
388398
OpenFile *fptr;
389399
#endif
390400

391-
Data_Get_Struct(self, struct buffer, buf);
401+
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);
392402
io = rb_convert_type(io, T_FILE, "IO", "to_io");
393403
GetOpenFile(io, fptr);
394404
rb_io_set_nonblock(fptr);
@@ -419,7 +429,7 @@ Coolio_Buffer_write_to(VALUE self, VALUE io)
419429
OpenFile *fptr;
420430
#endif
421431

422-
Data_Get_Struct(self, struct buffer, buf);
432+
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);
423433
io = rb_convert_type(io, T_FILE, "IO", "to_io");
424434
GetOpenFile(io, fptr);
425435
rb_io_set_nonblock(fptr);
@@ -438,11 +448,8 @@ Coolio_Buffer_write_to(VALUE self, VALUE io)
438448

439449
/* Create a new buffer */
440450
static struct buffer *
441-
buffer_new(void)
451+
buffer_init(struct buffer *buf)
442452
{
443-
struct buffer *buf;
444-
445-
buf = (struct buffer *) xmalloc(sizeof(struct buffer));
446453
buf->head = buf->tail = buf->pool_head = buf->pool_tail = 0;
447454
buf->size = 0;
448455
buf->node_size = default_node_size;

ext/cool.io/cool.io.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,7 @@ void Init_coolio_timer_watcher();
6868
void Init_coolio_stat_watcher();
6969
void Init_coolio_utils();
7070

71+
struct Coolio_Loop *Coolio_Loop_ptr(VALUE loop);
72+
struct Coolio_Watcher *Coolio_Watcher_ptr(VALUE watcher);
73+
7174
#endif

ext/cool.io/iowatcher.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ static VALUE Coolio_IOWatcher_initialize(int argc, VALUE *argv, VALUE self)
8282
else
8383
rb_raise(rb_eArgError, "invalid event type: '%s' (must be 'r', 'w', or 'rw')", flags_str);
8484

85-
Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
85+
watcher_data = Coolio_Watcher_ptr(self);
8686
io = rb_convert_type(io, T_FILE, "IO", "to_io");
8787

8888
watcher_data->dispatch_callback = Coolio_IOWatcher_dispatch_callback;

ext/cool.io/loop.c

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ static VALUE mCoolio = Qnil;
1414
static VALUE cCoolio_Loop = Qnil;
1515

1616
static VALUE Coolio_Loop_allocate(VALUE klass);
17-
static void Coolio_Loop_mark(struct Coolio_Loop *loop);
18-
static void Coolio_Loop_free(struct Coolio_Loop *loop);
17+
static void Coolio_Loop_free(void *data);
1918

2019
static VALUE Coolio_Loop_ev_loop_new(VALUE self, VALUE flags);
2120
static VALUE Coolio_Loop_run_once(int argc, VALUE *argv, VALUE self);
@@ -47,9 +46,26 @@ void Init_coolio_loop()
4746
rb_define_method(cCoolio_Loop, "run_nonblock", Coolio_Loop_run_nonblock, 0);
4847
}
4948

49+
static const rb_data_type_t Coolio_Loop_type = {
50+
"Coolio::Loop",
51+
{
52+
NULL,
53+
Coolio_Loop_free,
54+
},
55+
};
56+
57+
struct Coolio_Loop *Coolio_Loop_ptr(VALUE self)
58+
{
59+
struct Coolio_Loop *loop;
60+
61+
TypedData_Get_Struct(self, struct Coolio_Loop, &Coolio_Loop_type, loop);
62+
return loop;
63+
}
64+
5065
static VALUE Coolio_Loop_allocate(VALUE klass)
5166
{
52-
struct Coolio_Loop *loop = (struct Coolio_Loop *)xmalloc(sizeof(struct Coolio_Loop));
67+
struct Coolio_Loop *loop;
68+
VALUE obj = TypedData_Make_Struct(klass, struct Coolio_Loop, &Coolio_Loop_type, loop);
5369

5470
loop->ev_loop = 0;
5571
ev_init(&loop->timer, Coolio_Loop_timeout_callback);
@@ -58,15 +74,13 @@ static VALUE Coolio_Loop_allocate(VALUE klass)
5874
loop->eventbuf_size = DEFAULT_EVENTBUF_SIZE;
5975
loop->eventbuf = (struct Coolio_Event *)xmalloc(sizeof(struct Coolio_Event) * DEFAULT_EVENTBUF_SIZE);
6076

61-
return Data_Wrap_Struct(klass, Coolio_Loop_mark, Coolio_Loop_free, loop);
77+
return obj;
6278
}
6379

64-
static void Coolio_Loop_mark(struct Coolio_Loop *loop)
80+
static void Coolio_Loop_free(void *data)
6581
{
66-
}
82+
struct Coolio_Loop *loop = data;
6783

68-
static void Coolio_Loop_free(struct Coolio_Loop *loop)
69-
{
7084
if(!loop->ev_loop)
7185
return;
7286

@@ -80,7 +94,7 @@ static void Coolio_Loop_free(struct Coolio_Loop *loop)
8094
static VALUE Coolio_Loop_ev_loop_new(VALUE self, VALUE flags)
8195
{
8296
struct Coolio_Loop *loop_data;
83-
Data_Get_Struct(self, struct Coolio_Loop, loop_data);
97+
loop_data = Coolio_Loop_ptr(self);
8498

8599
if(loop_data->ev_loop)
86100
rb_raise(rb_eRuntimeError, "loop already initialized");
@@ -98,8 +112,8 @@ void Coolio_Loop_process_event(VALUE watcher, int revents)
98112

99113
/* The Global VM lock isn't held right now, but hopefully
100114
* we can still do this safely */
101-
Data_Get_Struct(watcher, struct Coolio_Watcher, watcher_data);
102-
Data_Get_Struct(watcher_data->loop, struct Coolio_Loop, loop_data);
115+
watcher_data = Coolio_Watcher_ptr(watcher);
116+
loop_data = Coolio_Loop_ptr(watcher_data->loop);
103117

104118
/* Well, what better place to explain how this all works than
105119
* where the most wonky and convoluted stuff is going on!
@@ -184,7 +198,7 @@ static VALUE Coolio_Loop_run_once(int argc, VALUE *argv, VALUE self)
184198
rb_raise(rb_eArgError, "time interval must be positive");
185199
}
186200

187-
Data_Get_Struct(self, struct Coolio_Loop, loop_data);
201+
loop_data = Coolio_Loop_ptr(self);
188202

189203
assert(loop_data->ev_loop && !loop_data->events_received);
190204

@@ -222,7 +236,7 @@ static VALUE Coolio_Loop_run_nonblock(VALUE self)
222236
struct Coolio_Loop *loop_data;
223237
VALUE nevents;
224238

225-
Data_Get_Struct(self, struct Coolio_Loop, loop_data);
239+
loop_data = Coolio_Loop_ptr(self);
226240

227241
assert(loop_data->ev_loop && !loop_data->events_received);
228242

@@ -247,7 +261,7 @@ static void Coolio_Loop_dispatch_events(struct Coolio_Loop *loop_data)
247261
if(loop_data->eventbuf[i].watcher == Qnil)
248262
continue;
249263

250-
Data_Get_Struct(loop_data->eventbuf[i].watcher, struct Coolio_Watcher, watcher_data);
264+
watcher_data = Coolio_Watcher_ptr(loop_data->eventbuf[i].watcher);
251265
watcher_data->dispatch_callback(loop_data->eventbuf[i].watcher, loop_data->eventbuf[i].revents);
252266
}
253267
}

ext/cool.io/stat_watcher.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ static VALUE Coolio_StatWatcher_initialize(int argc, VALUE *argv, VALUE self)
8989
path = rb_String(path);
9090
rb_iv_set(self, "@path", path);
9191

92-
Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
92+
watcher_data = Coolio_Watcher_ptr(self);
9393

9494
watcher_data->dispatch_callback = Coolio_StatWatcher_dispatch_callback;
9595
ev_stat_init(
@@ -119,8 +119,8 @@ static VALUE Coolio_StatWatcher_attach(VALUE self, VALUE loop)
119119
if(!rb_obj_is_kind_of(loop, cCoolio_Loop))
120120
rb_raise(rb_eArgError, "expected loop to be an instance of Coolio::Loop, not %s", RSTRING_PTR(rb_inspect(loop)));
121121

122-
Data_Get_Struct(loop, struct Coolio_Loop, loop_data);
123-
Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
122+
loop_data = Coolio_Loop_ptr(loop);
123+
watcher_data = Coolio_Watcher_ptr(self);
124124

125125
if(watcher_data->loop != Qnil)
126126
Coolio_StatWatcher_detach(self);
@@ -206,7 +206,7 @@ static void Coolio_StatWatcher_libev_callback(struct ev_loop *ev_loop, struct ev
206206
static void Coolio_StatWatcher_dispatch_callback(VALUE self, int revents)
207207
{
208208
struct Coolio_Watcher *watcher_data;
209-
Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
209+
watcher_data = Coolio_Watcher_ptr(self);
210210

211211
VALUE previous_statdata = Coolio_StatInfo_build(&watcher_data->event_types.ev_stat.prev);
212212
VALUE current_statdata = Coolio_StatInfo_build(&watcher_data->event_types.ev_stat.attr);

ext/cool.io/timer_watcher.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ static VALUE Coolio_TimerWatcher_initialize(int argc, VALUE *argv, VALUE self)
6868
rb_iv_set(self, "@interval", interval);
6969
rb_iv_set(self, "@repeating", repeating);
7070

71-
Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
71+
watcher_data = Coolio_Watcher_ptr(self);
7272

7373
watcher_data->dispatch_callback = Coolio_TimerWatcher_dispatch_callback;
7474
ev_timer_init(
@@ -98,8 +98,8 @@ static VALUE Coolio_TimerWatcher_attach(VALUE self, VALUE loop)
9898
if(!rb_obj_is_kind_of(loop, cCoolio_Loop))
9999
rb_raise(rb_eArgError, "expected loop to be an instance of Coolio::Loop, not %s", RSTRING_PTR(rb_inspect(loop)));
100100

101-
Data_Get_Struct(loop, struct Coolio_Loop, loop_data);
102-
Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
101+
loop_data = Coolio_Loop_ptr(loop);
102+
watcher_data = Coolio_Watcher_ptr(self);
103103

104104
if(watcher_data->loop != Qnil)
105105
Coolio_TimerWatcher_detach(self);
@@ -180,12 +180,12 @@ static VALUE Coolio_TimerWatcher_reset(VALUE self)
180180
struct Coolio_Watcher *watcher_data;
181181
struct Coolio_Loop *loop_data;
182182

183-
Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
183+
watcher_data = Coolio_Watcher_ptr(self);
184184

185185
if(watcher_data->loop == Qnil)
186186
rb_raise(rb_eRuntimeError, "not attached to a loop");
187187

188-
Data_Get_Struct(watcher_data->loop, struct Coolio_Loop, loop_data);
188+
loop_data = Coolio_Loop_ptr(watcher_data->loop);
189189

190190
ev_timer_again(loop_data->ev_loop, &watcher_data->event_types.ev_timer);
191191

0 commit comments

Comments
 (0)