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



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

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



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

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



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

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



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

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



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

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

  loop_signal(loop);
  return self;
}

#stopObject



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

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

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

#unwatch(key) ⇒ Object



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

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



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

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, NUM2INT(fd), sym_to_events(rw), RTEST(oneshot));
  return self;
}

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



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

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



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

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;  
}