Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 30 additions & 23 deletions ext/cool.io/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ static VALUE mCoolio = Qnil;
static VALUE cCoolio_Buffer = Qnil;

static VALUE Coolio_Buffer_allocate(VALUE klass);
static void Coolio_Buffer_mark(struct buffer *);
static void Coolio_Buffer_free(struct buffer *);
static void Coolio_Buffer_mark(void *);
static void Coolio_Buffer_free(void *);

static VALUE Coolio_Buffer_default_node_size(VALUE klass);
static VALUE Coolio_Buffer_set_default_node_size(VALUE klass, VALUE size);
Expand All @@ -64,7 +64,7 @@ static VALUE Coolio_Buffer_to_str(VALUE self);
static VALUE Coolio_Buffer_read_from(VALUE self, VALUE io);
static VALUE Coolio_Buffer_write_to(VALUE self, VALUE io);

static struct buffer *buffer_new(void);
static struct buffer *buffer_init(struct buffer *);
static void buffer_clear(struct buffer * buf);
static void buffer_free(struct buffer * buf);
static void buffer_free_pool(struct buffer * buf);
Expand All @@ -86,8 +86,6 @@ static int buffer_write_to(struct buffer * buf, int fd);
void
Init_coolio_buffer()
{
VALUE cCoolio_IO;

mCoolio = rb_define_module("Coolio");
cCoolio_Buffer = rb_define_class_under(mCoolio, "Buffer", rb_cObject);
rb_define_alloc_func(cCoolio_Buffer, Coolio_Buffer_allocate);
Expand All @@ -114,21 +112,33 @@ Init_coolio_buffer()
rb_define_const(cCoolio_Buffer, "MAX_SIZE", INT2NUM(MAX_BUFFER_SIZE));
}

static const rb_data_type_t Coolio_Buffer_type = {
"Coolio::Buffer",
{
Coolio_Buffer_mark,
Coolio_Buffer_free,
}
};

static VALUE
Coolio_Buffer_allocate(VALUE klass)
{
return Data_Wrap_Struct(klass, Coolio_Buffer_mark, Coolio_Buffer_free, buffer_new());
struct buffer *buf;
VALUE buffer = TypedData_Make_Struct(klass, struct buffer, &Coolio_Buffer_type, buf);

buffer_init(buf);
return buffer;
}

static void
Coolio_Buffer_mark(struct buffer * buf)
Coolio_Buffer_mark(void *buf)
{
/* Naively discard the memory pool whenever Ruby garbage collects */
buffer_free_pool(buf);
}

static void
Coolio_Buffer_free(struct buffer * buf)
Coolio_Buffer_free(void * buf)
{
buffer_free(buf);
}
Expand Down Expand Up @@ -188,7 +198,7 @@ Coolio_Buffer_initialize(int argc, VALUE * argv, VALUE self)
struct buffer *buf;

if (rb_scan_args(argc, argv, "01", &node_size_obj) == 1) {
Data_Get_Struct(self, struct buffer, buf);
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);

/*
* Make sure we're not changing the buffer size after data
Expand All @@ -212,7 +222,7 @@ static VALUE
Coolio_Buffer_clear(VALUE self)
{
struct buffer *buf;
Data_Get_Struct(self, struct buffer, buf);
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);

buffer_clear(buf);

Expand All @@ -229,7 +239,7 @@ static VALUE
Coolio_Buffer_size(VALUE self)
{
struct buffer *buf;
Data_Get_Struct(self, struct buffer, buf);
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);

return INT2NUM(buf->size);
}
Expand All @@ -244,7 +254,7 @@ static VALUE
Coolio_Buffer_empty(VALUE self)
{
struct buffer *buf;
Data_Get_Struct(self, struct buffer, buf);
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);

return buf->size > 0 ? Qfalse : Qtrue;
}
Expand All @@ -259,7 +269,7 @@ static VALUE
Coolio_Buffer_append(VALUE self, VALUE data)
{
struct buffer *buf;
Data_Get_Struct(self, struct buffer, buf);
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);

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

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

Data_Get_Struct(self, struct buffer, buf);
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);

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

Data_Get_Struct(self, struct buffer, buf);
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);

if (buffer_read_frame(buf, data, mark_c)) {
return Qtrue;
Expand All @@ -361,7 +371,7 @@ Coolio_Buffer_to_str(VALUE self)
VALUE str;
struct buffer *buf;

Data_Get_Struct(self, struct buffer, buf);
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);

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

Data_Get_Struct(self, struct buffer, buf);
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);
io = rb_convert_type(io, T_FILE, "IO", "to_io");
GetOpenFile(io, fptr);
rb_io_set_nonblock(fptr);
Expand Down Expand Up @@ -419,7 +429,7 @@ Coolio_Buffer_write_to(VALUE self, VALUE io)
OpenFile *fptr;
#endif

Data_Get_Struct(self, struct buffer, buf);
TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf);
io = rb_convert_type(io, T_FILE, "IO", "to_io");
GetOpenFile(io, fptr);
rb_io_set_nonblock(fptr);
Expand All @@ -438,11 +448,8 @@ Coolio_Buffer_write_to(VALUE self, VALUE io)

/* Create a new buffer */
static struct buffer *
buffer_new(void)
buffer_init(struct buffer *buf)
{
struct buffer *buf;

buf = (struct buffer *) xmalloc(sizeof(struct buffer));
buf->head = buf->tail = buf->pool_head = buf->pool_tail = 0;
buf->size = 0;
buf->node_size = default_node_size;
Expand Down
3 changes: 3 additions & 0 deletions ext/cool.io/cool.io.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,7 @@ void Init_coolio_timer_watcher();
void Init_coolio_stat_watcher();
void Init_coolio_utils();

struct Coolio_Loop *Coolio_Loop_ptr(VALUE loop);
struct Coolio_Watcher *Coolio_Watcher_ptr(VALUE watcher);

#endif
2 changes: 1 addition & 1 deletion ext/cool.io/iowatcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ static VALUE Coolio_IOWatcher_initialize(int argc, VALUE *argv, VALUE self)
else
rb_raise(rb_eArgError, "invalid event type: '%s' (must be 'r', 'w', or 'rw')", flags_str);

Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
watcher_data = Coolio_Watcher_ptr(self);
io = rb_convert_type(io, T_FILE, "IO", "to_io");

watcher_data->dispatch_callback = Coolio_IOWatcher_dispatch_callback;
Expand Down
42 changes: 28 additions & 14 deletions ext/cool.io/loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ static VALUE mCoolio = Qnil;
static VALUE cCoolio_Loop = Qnil;

static VALUE Coolio_Loop_allocate(VALUE klass);
static void Coolio_Loop_mark(struct Coolio_Loop *loop);
static void Coolio_Loop_free(struct Coolio_Loop *loop);
static void Coolio_Loop_free(void *data);

static VALUE Coolio_Loop_ev_loop_new(VALUE self, VALUE flags);
static VALUE Coolio_Loop_run_once(int argc, VALUE *argv, VALUE self);
Expand Down Expand Up @@ -47,9 +46,26 @@ void Init_coolio_loop()
rb_define_method(cCoolio_Loop, "run_nonblock", Coolio_Loop_run_nonblock, 0);
}

static const rb_data_type_t Coolio_Loop_type = {
"Coolio::Loop",
{
NULL,
Coolio_Loop_free,
},
};

struct Coolio_Loop *Coolio_Loop_ptr(VALUE self)
{
struct Coolio_Loop *loop;

TypedData_Get_Struct(self, struct Coolio_Loop, &Coolio_Loop_type, loop);
return loop;
}

static VALUE Coolio_Loop_allocate(VALUE klass)
{
struct Coolio_Loop *loop = (struct Coolio_Loop *)xmalloc(sizeof(struct Coolio_Loop));
struct Coolio_Loop *loop;
VALUE obj = TypedData_Make_Struct(klass, struct Coolio_Loop, &Coolio_Loop_type, loop);

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

return Data_Wrap_Struct(klass, Coolio_Loop_mark, Coolio_Loop_free, loop);
return obj;
}

static void Coolio_Loop_mark(struct Coolio_Loop *loop)
static void Coolio_Loop_free(void *data)
{
}
struct Coolio_Loop *loop = data;

static void Coolio_Loop_free(struct Coolio_Loop *loop)
{
if(!loop->ev_loop)
return;

Expand All @@ -80,7 +94,7 @@ static void Coolio_Loop_free(struct Coolio_Loop *loop)
static VALUE Coolio_Loop_ev_loop_new(VALUE self, VALUE flags)
{
struct Coolio_Loop *loop_data;
Data_Get_Struct(self, struct Coolio_Loop, loop_data);
loop_data = Coolio_Loop_ptr(self);

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

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

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

Data_Get_Struct(self, struct Coolio_Loop, loop_data);
loop_data = Coolio_Loop_ptr(self);

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

Expand Down Expand Up @@ -222,7 +236,7 @@ static VALUE Coolio_Loop_run_nonblock(VALUE self)
struct Coolio_Loop *loop_data;
VALUE nevents;

Data_Get_Struct(self, struct Coolio_Loop, loop_data);
loop_data = Coolio_Loop_ptr(self);

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

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

Data_Get_Struct(loop_data->eventbuf[i].watcher, struct Coolio_Watcher, watcher_data);
watcher_data = Coolio_Watcher_ptr(loop_data->eventbuf[i].watcher);
watcher_data->dispatch_callback(loop_data->eventbuf[i].watcher, loop_data->eventbuf[i].revents);
}
}
8 changes: 4 additions & 4 deletions ext/cool.io/stat_watcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ static VALUE Coolio_StatWatcher_initialize(int argc, VALUE *argv, VALUE self)
path = rb_String(path);
rb_iv_set(self, "@path", path);

Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
watcher_data = Coolio_Watcher_ptr(self);

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

Data_Get_Struct(loop, struct Coolio_Loop, loop_data);
Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
loop_data = Coolio_Loop_ptr(loop);
watcher_data = Coolio_Watcher_ptr(self);

if(watcher_data->loop != Qnil)
Coolio_StatWatcher_detach(self);
Expand Down Expand Up @@ -206,7 +206,7 @@ static void Coolio_StatWatcher_libev_callback(struct ev_loop *ev_loop, struct ev
static void Coolio_StatWatcher_dispatch_callback(VALUE self, int revents)
{
struct Coolio_Watcher *watcher_data;
Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
watcher_data = Coolio_Watcher_ptr(self);

VALUE previous_statdata = Coolio_StatInfo_build(&watcher_data->event_types.ev_stat.prev);
VALUE current_statdata = Coolio_StatInfo_build(&watcher_data->event_types.ev_stat.attr);
Expand Down
10 changes: 5 additions & 5 deletions ext/cool.io/timer_watcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static VALUE Coolio_TimerWatcher_initialize(int argc, VALUE *argv, VALUE self)
rb_iv_set(self, "@interval", interval);
rb_iv_set(self, "@repeating", repeating);

Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
watcher_data = Coolio_Watcher_ptr(self);

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

Data_Get_Struct(loop, struct Coolio_Loop, loop_data);
Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
loop_data = Coolio_Loop_ptr(loop);
watcher_data = Coolio_Watcher_ptr(self);

if(watcher_data->loop != Qnil)
Coolio_TimerWatcher_detach(self);
Expand Down Expand Up @@ -180,12 +180,12 @@ static VALUE Coolio_TimerWatcher_reset(VALUE self)
struct Coolio_Watcher *watcher_data;
struct Coolio_Loop *loop_data;

Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
watcher_data = Coolio_Watcher_ptr(self);

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

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

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

Expand Down
Loading