Sha256: 7244738ec46e306e0ff52ffddcbbacff917d7a8cc4782ea4e91449437cfb235d

Contents?: true

Size: 1.93 KB

Versions: 9

Compression:

Stored size: 1.93 KB

Contents

#include "polyphony.h"
#include "ring_buffer.h"

typedef struct event {
  VALUE waiting_fiber;
} Event_t;

VALUE cEvent = Qnil;

static void Event_mark(void *ptr) {
  Event_t *event = ptr;
  rb_gc_mark(event->waiting_fiber);
}

static void Event_free(void *ptr) {
  xfree(ptr);
}

static size_t Event_size(const void *ptr) {
  return sizeof(Event_t);
}

static const rb_data_type_t Event_type = {
  "Event",
  {Event_mark, Event_free, Event_size,},
  0, 0, 0
};

static VALUE Event_allocate(VALUE klass) {
  Event_t *event;

  event = ALLOC(Event_t);
  return TypedData_Wrap_Struct(klass, &Event_type, event);
}

#define GetEvent(obj, event) \
  TypedData_Get_Struct((obj), Event_t, &Event_type, (event))

static VALUE Event_initialize(VALUE self) {
  Event_t *event;
  GetEvent(self, event);

  event->waiting_fiber = Qnil;

  return self;
}

VALUE Event_signal(int argc, VALUE *argv, VALUE self) {
  VALUE value = argc > 0 ? argv[0] : Qnil;
  Event_t *event;
  GetEvent(self, event);

  if (event->waiting_fiber != Qnil) {
    Fiber_make_runnable(event->waiting_fiber, value);
    event->waiting_fiber = Qnil;
  }
  return self;
}

VALUE Event_await(VALUE self) {
  Event_t *event;
  GetEvent(self, event);

  if (event->waiting_fiber != Qnil)
    rb_raise(rb_eRuntimeError, "Event is already awaited by another fiber");

  VALUE backend = rb_ivar_get(rb_thread_current(), ID_ivar_backend);
  event->waiting_fiber = rb_fiber_current();
  VALUE switchpoint_result = __BACKEND__.wait_event(backend, Qnil);
  event->waiting_fiber = Qnil;

  RAISE_IF_EXCEPTION(switchpoint_result);
  RB_GC_GUARD(backend);
  RB_GC_GUARD(switchpoint_result);

  return switchpoint_result;
}

void Init_Event() {
  cEvent = rb_define_class_under(mPolyphony, "Event", rb_cData);
  rb_define_alloc_func(cEvent, Event_allocate);

  rb_define_method(cEvent, "initialize", Event_initialize, 0);
  rb_define_method(cEvent, "await", Event_await, 0);
  rb_define_method(cEvent, "signal", Event_signal, -1);
}

Version data entries

9 entries across 9 versions & 1 rubygems

Version Path
polyphony-0.47.5.1 ext/polyphony/event.c
polyphony-0.47.5 ext/polyphony/event.c
polyphony-0.47.4 ext/polyphony/event.c
polyphony-0.47.3 ext/polyphony/event.c
polyphony-0.47.2 ext/polyphony/event.c
polyphony-0.47.1 ext/polyphony/event.c
polyphony-0.47.0 ext/polyphony/event.c
polyphony-0.46.1 ext/polyphony/event.c
polyphony-0.46.0 ext/polyphony/event.c