Class: Ever::Loop

Inherits:
Object
  • Object
show all
Defined in:
ext/ever/loop.c

Instance Method Summary collapse

Constructor Details

#initializeObject

of a blocking event loop (waking it up) in a thread-safe, signal-safe manner



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'ext/ever/loop.c', line 117

static VALUE Loop_initialize(VALUE self) {
  Loop_t *loop;
  GetLoop(self, loop);

  loop->ev_loop = ev_loop_new(EVFLAG_NOSIGMASK);
  // start async watcher used for breaking a poll op (from another thread)
  ev_async_init(&loop->break_async, break_async_callback);
  ev_async_start(loop->ev_loop, &loop->break_async);
  // the break_async watcher is unreferenced, in order for Loop_poll to not
  // block when no other watcher is active
  ev_unref(loop->ev_loop);

  loop->active_watchers = rb_hash_new();
  loop->free_watchers = rb_ary_new();
  loop->queued_events = rb_ary_new();

  loop->stop = 0;
  loop->in_ev_loop = 0;

  return Qnil;
}

Instance Method Details

#eachObject



139
140
141
142
143
144
145
146
147
148
149
# File 'ext/ever/loop.c', line 139

VALUE Loop_each(VALUE self) {
  Loop_t *loop;
  GetLoop(self, loop);

  loop->stop = 0;
  while (!loop->stop) {
    if (RARRAY_LEN(loop->queued_events) == 0) loop_run_ev_loop(loop);
    loop_yield_queued_events(loop);
  }
  return self;
}

#emit(key) ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
170
# File 'ext/ever/loop.c', line 159

VALUE Loop_emit(VALUE self, VALUE key) {
  Loop_t *loop;
  GetLoop(self, loop);

  if (key == SYM_stop)
    loop->stop = 1;
  else
    rb_ary_push(loop->queued_events, key);

  loop_signal(loop);
  return key;
}

#next_eventObject



151
152
153
154
155
156
157
# File 'ext/ever/loop.c', line 151

VALUE Loop_next_event(VALUE self) {
  Loop_t *loop;
  GetLoop(self, loop);

  if (RARRAY_LEN(loop->queued_events) == 0) loop_run_ev_loop(loop);
  return rb_ary_shift(loop->queued_events);
}

#signalObject



172
173
174
175
176
177
178
# File 'ext/ever/loop.c', line 172

VALUE Loop_signal(VALUE self) {
  Loop_t *loop;
  GetLoop(self, loop);

  loop_signal(loop);
  return self;
}

#stopObject



180
181
182
183
184
185
186
187
# File 'ext/ever/loop.c', line 180

VALUE Loop_stop(VALUE self) {
  Loop_t *loop;
  GetLoop(self, loop);

  loop->stop = 1;
  loop_signal(loop);
  return self;
}

#unwatch(key) ⇒ Object



222
223
224
225
226
227
228
229
230
231
232
233
# File 'ext/ever/loop.c', line 222

VALUE Loop_unwatch(VALUE self, VALUE key) {
  Loop_t *loop;
  GetLoop(self, loop);

  VALUE watcher = rb_hash_delete(loop->active_watchers, key);
  if (watcher == Qnil) return self;

  Watcher_stop(watcher);
  rb_ary_push(loop->free_watchers, watcher);

  return self;
}

#watch_fd(key, fd, rw, oneshot) ⇒ Object



189
190
191
192
193
194
195
196
197
198
# File 'ext/ever/loop.c', line 189

VALUE Loop_watch_fd(VALUE self, VALUE key, VALUE fd, VALUE rw, VALUE oneshot) {
  Loop_t *loop;
  GetLoop(self, loop);

  if (rb_hash_aref(loop->active_watchers, key) != Qnil)
    rb_raise(rb_eRuntimeError, "Duplicate event key detected, event key must be unique");

  loop_watch_fd(loop, key, FIX2INT(fd), sym_to_events(rw), RTEST(oneshot));
  return self;
}

#watch_io(key, io, rw, oneshot) ⇒ Object



200
201
202
203
204
205
206
207
208
209
# File 'ext/ever/loop.c', line 200

VALUE Loop_watch_io(VALUE self, VALUE key, VALUE io, VALUE rw, VALUE oneshot) {
  Loop_t *loop;
  GetLoop(self, loop);

  if (rb_hash_aref(loop->active_watchers, key) != Qnil)
    rb_raise(rb_eRuntimeError, "Duplicate event key detected, event key must be unique");

  loop_watch_fd(loop, key, fd_from_io(io), sym_to_events(rw), RTEST(oneshot));
  return self;
}

#watch_timer(key, timeout, interval) ⇒ Object



211
212
213
214
215
216
217
218
219
220
# File 'ext/ever/loop.c', line 211

VALUE Loop_watch_timer(VALUE self, VALUE key, VALUE timeout, VALUE interval) {
  Loop_t *loop;
  GetLoop(self, loop);

  if (rb_hash_aref(loop->active_watchers, key) != Qnil)
    rb_raise(rb_eRuntimeError, "Duplicate event key detected, event key must be unique");

  loop_watch_timer(loop, key, NUM2DBL(timeout), NUM2DBL(interval));
  return self;
}