uringmachine 0.31.0 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,88 +2,88 @@
2
2
  #include <ruby/io/buffer.h>
3
3
  #include "um.h"
4
4
 
5
- inline void connection_add_segment(struct um_connection *conn, struct um_segment *segment) {
5
+ inline void io_add_segment(struct um_io *io, struct um_segment *segment) {
6
6
  segment->next = NULL;
7
- if (conn->tail) {
8
- conn->tail->next = segment;
9
- conn->tail = segment;
7
+ if (io->tail) {
8
+ io->tail->next = segment;
9
+ io->tail = segment;
10
10
  }
11
11
  else
12
- conn->head = conn->tail = segment;
13
- conn->pending_bytes += segment->len;
12
+ io->head = io->tail = segment;
13
+ io->pending_bytes += segment->len;
14
14
  }
15
15
 
16
- inline int connection_process_op_result(struct um_connection *conn, struct um_op_result *result) {
16
+ inline int io_process_op_result(struct um_io *io, struct um_op_result *result) {
17
17
  if (likely(result->res > 0)) {
18
18
  if (likely(result->segment)) {
19
- connection_add_segment(conn, result->segment);
19
+ io_add_segment(io, result->segment);
20
20
  result->segment = NULL;
21
21
  }
22
22
  }
23
23
  else
24
- conn->eof = 1;
24
+ io->eof = 1;
25
25
 
26
26
  return result->res;
27
27
  }
28
28
 
29
- #define CONNECTION_OP_FLAGS (OP_F_MULTISHOT | OP_F_BUFFER_POOL)
29
+ #define IO_OP_FLAGS (OP_F_MULTISHOT | OP_F_BUFFER_POOL)
30
30
 
31
- void connection_multishot_op_start(struct um_connection *conn) {
32
- if (!conn->op)
33
- conn->op = um_op_acquire(conn->machine);
31
+ void io_multishot_op_start(struct um_io *io) {
32
+ if (!io->op)
33
+ io->op = um_op_acquire(io->machine);
34
34
  struct io_uring_sqe *sqe;
35
35
 
36
- bp_ensure_commit_level(conn->machine);
36
+ bp_ensure_commit_level(io->machine);
37
37
 
38
- switch (conn->mode) {
39
- case CONNECTION_FD:
40
- um_prep_op(conn->machine, conn->op, OP_READ_MULTISHOT, 2, CONNECTION_OP_FLAGS);
41
- sqe = um_get_sqe(conn->machine, conn->op);
42
- io_uring_prep_read_multishot(sqe, conn->fd, 0, -1, BP_BGID);
38
+ switch (io->mode) {
39
+ case IO_FD:
40
+ um_prep_op(io->machine, io->op, OP_READ_MULTISHOT, 2, IO_OP_FLAGS);
41
+ sqe = um_get_sqe(io->machine, io->op);
42
+ io_uring_prep_read_multishot(sqe, io->fd, 0, -1, BP_BGID);
43
43
  break;
44
- case CONNECTION_SOCKET:
45
- um_prep_op(conn->machine, conn->op, OP_RECV_MULTISHOT, 2, CONNECTION_OP_FLAGS);
46
- sqe = um_get_sqe(conn->machine, conn->op);
47
- io_uring_prep_recv_multishot(sqe, conn->fd, NULL, 0, 0);
44
+ case IO_SOCKET:
45
+ um_prep_op(io->machine, io->op, OP_RECV_MULTISHOT, 2, IO_OP_FLAGS);
46
+ sqe = um_get_sqe(io->machine, io->op);
47
+ io_uring_prep_recv_multishot(sqe, io->fd, NULL, 0, 0);
48
48
  sqe->buf_group = BP_BGID;
49
49
  sqe->flags |= IOSQE_BUFFER_SELECT;
50
50
  break;
51
51
  default:
52
52
  um_raise_internal_error("Invalid multishot op");
53
53
  }
54
- conn->op->bp_commit_level = conn->machine->bp_commit_level;
54
+ io->op->bp_commit_level = io->machine->bp_commit_level;
55
55
  }
56
56
 
57
- void connection_multishot_op_stop(struct um_connection *conn) {
58
- assert(!conn->op);
57
+ void io_multishot_op_stop(struct um_io *io) {
58
+ assert(!io->op);
59
59
 
60
- if (!(conn->op->flags & OP_F_CQE_DONE)) {
61
- conn->op->flags |= OP_F_ASYNC;
62
- um_cancel_op(conn->machine, conn->op);
60
+ if (!(io->op->flags & OP_F_CQE_DONE)) {
61
+ io->op->flags |= OP_F_ASYNC;
62
+ um_cancel_op(io->machine, io->op);
63
63
  }
64
64
  else
65
- um_op_release(conn->machine, conn->op);
66
- conn->op = NULL;
65
+ um_op_release(io->machine, io->op);
66
+ io->op = NULL;
67
67
  }
68
68
 
69
- void um_connection_cleanup(struct um_connection *conn) {
70
- if (conn->op) connection_multishot_op_stop(conn);
69
+ void um_io_cleanup(struct um_io *io) {
70
+ if (io->op) io_multishot_op_stop(io);
71
71
 
72
- while (conn->head) {
73
- struct um_segment *next = conn->head->next;
74
- um_segment_checkin(conn->machine, conn->head);
75
- conn->head = next;
72
+ while (io->head) {
73
+ struct um_segment *next = io->head->next;
74
+ um_segment_checkin(io->machine, io->head);
75
+ io->head = next;
76
76
  }
77
- conn->pending_bytes = 0;
77
+ io->pending_bytes = 0;
78
78
  }
79
79
 
80
80
  // returns true if case of ENOBUFS error, sets more to true if more data forthcoming
81
- inline int connection_process_segments(
82
- struct um_connection *conn, size_t *total_bytes, int *more) {
81
+ inline int io_process_segments(
82
+ struct um_io *io, size_t *total_bytes, int *more) {
83
83
 
84
84
  *more = 0;
85
- struct um_op_result *result = &conn->op->result;
86
- conn->op->flags &= ~OP_F_CQE_SEEN;
85
+ struct um_op_result *result = &io->op->result;
86
+ io->op->flags &= ~OP_F_CQE_SEEN;
87
87
  while (result) {
88
88
  if (unlikely(result->res == -ENOBUFS)) {
89
89
  *more = 0;
@@ -97,142 +97,141 @@ inline int connection_process_segments(
97
97
 
98
98
  *more = (result->flags & IORING_CQE_F_MORE);
99
99
  *total_bytes += result->res;
100
- connection_process_op_result(conn, result);
100
+ io_process_op_result(io, result);
101
101
  result = result->next;
102
102
  }
103
103
  return false;
104
104
  }
105
105
 
106
- void connection_clear(struct um_connection *conn) {
107
- if (conn->op && conn->machine->ring_initialized) {
108
- if (OP_CQE_SEEN_P(conn->op)) {
106
+ void io_clear(struct um_io *io) {
107
+ if (io->op && io->machine->ring_initialized) {
108
+ if (OP_CQE_SEEN_P(io->op)) {
109
109
  size_t total_bytes = 0;
110
110
  int more = false;
111
- connection_process_segments(conn, &total_bytes, &more);
112
- um_op_multishot_results_clear(conn->machine, conn->op);
111
+ io_process_segments(io, &total_bytes, &more);
112
+ um_op_multishot_results_clear(io->machine, io->op);
113
113
  }
114
114
 
115
- if (OP_CQE_DONE_P(conn->op))
116
- um_op_release(conn->machine, conn->op);
115
+ if (OP_CQE_DONE_P(io->op))
116
+ um_op_release(io->machine, io->op);
117
117
  else
118
- um_cancel_op_and_discard_cqe(conn->machine, conn->op);
118
+ um_cancel_op_and_discard_cqe(io->machine, io->op);
119
119
 
120
- conn->op = NULL;
120
+ io->op = NULL;
121
121
  }
122
122
 
123
- while (conn->head) {
124
- struct um_segment *next = conn->head->next;
125
- um_segment_checkin(conn->machine, conn->head);
126
- conn->head = next;
123
+ while (io->head) {
124
+ struct um_segment *next = io->head->next;
125
+ um_segment_checkin(io->machine, io->head);
126
+ io->head = next;
127
127
  }
128
- conn->pending_bytes = 0;
128
+ io->pending_bytes = 0;
129
129
 
130
- if (conn->working_buffer) {
131
- bp_buffer_checkin(conn->machine, conn->working_buffer);
132
- conn->working_buffer = NULL;
130
+ if (io->working_buffer) {
131
+ bp_buffer_checkin(io->machine, io->working_buffer);
132
+ io->working_buffer = NULL;
133
133
  }
134
134
  }
135
135
 
136
- inline void connection_await_segments(struct um_connection *conn) {
137
- if (unlikely(!conn->op)) connection_multishot_op_start(conn);
136
+ inline void io_await_segments(struct um_io *io) {
137
+ if (unlikely(!io->op)) io_multishot_op_start(io);
138
138
 
139
- if (!OP_CQE_SEEN_P(conn->op)) {
140
- conn->op->flags &= ~OP_F_ASYNC;
141
- VALUE ret = um_yield(conn->machine);
142
- conn->op->flags |= OP_F_ASYNC;
143
- if (!OP_CQE_SEEN_P(conn->op)) RAISE_IF_EXCEPTION(ret);
139
+ if (!OP_CQE_SEEN_P(io->op)) {
140
+ io->op->flags &= ~OP_F_ASYNC;
141
+ VALUE ret = um_yield(io->machine);
142
+ io->op->flags |= OP_F_ASYNC;
143
+ if (!OP_CQE_SEEN_P(io->op)) RAISE_IF_EXCEPTION(ret);
144
144
  RB_GC_GUARD(ret);
145
145
  }
146
146
  }
147
147
 
148
- int connection_get_more_segments_bp(struct um_connection *conn) {
148
+ int io_get_more_segments_bp(struct um_io *io) {
149
149
  size_t total_bytes = 0;
150
150
  int more = false;
151
151
  int enobufs = false;
152
152
 
153
153
  while (1) {
154
- if (unlikely(conn->eof)) return 0;
154
+ if (unlikely(io->eof)) return 0;
155
155
 
156
- connection_await_segments(conn);
157
- enobufs = connection_process_segments(conn, &total_bytes, &more);
158
- um_op_multishot_results_clear(conn->machine, conn->op);
156
+ io_await_segments(io);
157
+ enobufs = io_process_segments(io, &total_bytes, &more);
158
+ um_op_multishot_results_clear(io->machine, io->op);
159
159
  if (unlikely(enobufs)) {
160
- int should_restart = conn->pending_bytes < (conn->machine->bp_buffer_size * 4);
161
- // int same_threshold = conn->op->bp_commit_level == conn->machine->bp_commit_level;
160
+ int should_restart = io->pending_bytes < (io->machine->bp_buffer_size * 4);
161
+ // int same_threshold = io->op->bp_commit_level == io->machine->bp_commit_level;
162
162
 
163
163
  // fprintf(stderr, "%p enobufs total: %ld pending: %ld threshold: %ld bc: %d (same: %d, restart: %d)\n",
164
- // conn,
165
- // total_bytes, conn->pending_bytes, conn->machine->bp_commit_level,
166
- // conn->machine->bp_buffer_count,
164
+ // io,
165
+ // total_bytes, io->pending_bytes, io->machine->bp_commit_level,
166
+ // io->machine->bp_buffer_count,
167
167
  // same_threshold, should_restart
168
168
  // );
169
169
 
170
- // If multiple connection ops are happening at the same time, they'll all
170
+ // If multiple IO ops are happening at the same time, they'll all
171
171
  // get ENOBUFS! We track the commit threshold in the op in order to
172
172
  // prevent running bp_handle_enobufs() more than once.
173
173
 
174
174
  if (should_restart) {
175
- if (conn->op->bp_commit_level == conn->machine->bp_commit_level)
176
- bp_handle_enobufs(conn->machine);
175
+ if (io->op->bp_commit_level == io->machine->bp_commit_level)
176
+ bp_handle_enobufs(io->machine);
177
177
 
178
- um_op_release(conn->machine, conn->op);
179
- conn->op = NULL;
180
- // connection_multishot_op_start(conn);
178
+ um_op_release(io->machine, io->op);
179
+ io->op = NULL;
181
180
  }
182
181
  else {
183
- um_op_release(conn->machine, conn->op);
184
- conn->op = NULL;
182
+ um_op_release(io->machine, io->op);
183
+ io->op = NULL;
185
184
  }
186
185
 
187
186
  if (total_bytes) return total_bytes;
188
187
  }
189
188
  else {
190
189
  if (more)
191
- conn->op->flags &= ~OP_F_CQE_SEEN;
192
- if (total_bytes || conn->eof) return total_bytes;
190
+ io->op->flags &= ~OP_F_CQE_SEEN;
191
+ if (total_bytes || io->eof) return total_bytes;
193
192
  }
194
193
  }
195
194
  }
196
195
 
197
- int connection_get_more_segments_ssl(struct um_connection *conn) {
198
- if (!conn->working_buffer)
199
- conn->working_buffer = bp_buffer_checkout(conn->machine);
196
+ int io_get_more_segments_ssl(struct um_io *io) {
197
+ if (!io->working_buffer)
198
+ io->working_buffer = bp_buffer_checkout(io->machine);
200
199
 
201
- char *ptr = conn->working_buffer->buf + conn->working_buffer->pos;
202
- size_t maxlen = conn->working_buffer->len - conn->working_buffer->pos;
203
- int res = um_ssl_read_raw(conn->machine, conn->target, ptr, maxlen);
200
+ char *ptr = io->working_buffer->buf + io->working_buffer->pos;
201
+ size_t maxlen = io->working_buffer->len - io->working_buffer->pos;
202
+ int res = um_ssl_read_raw(io->machine, io->target, ptr, maxlen);
204
203
  if (res == 0) return 0;
205
204
  if (res < 0) rb_raise(eUMError, "Failed to read segment");
206
205
 
207
- struct um_segment *segment = bp_buffer_consume(conn->machine, conn->working_buffer, res);
206
+ struct um_segment *segment = bp_buffer_consume(io->machine, io->working_buffer, res);
208
207
  if ((size_t)res == maxlen) {
209
- bp_buffer_checkin(conn->machine, conn->working_buffer);
210
- conn->working_buffer = NULL;
208
+ bp_buffer_checkin(io->machine, io->working_buffer);
209
+ io->working_buffer = NULL;
211
210
  }
212
- connection_add_segment(conn, segment);
211
+ io_add_segment(io, segment);
213
212
  return 1;
214
213
  }
215
214
 
216
- int connection_get_more_segments(struct um_connection *conn) {
217
- switch (conn->mode) {
218
- case CONNECTION_FD:
219
- case CONNECTION_SOCKET:
220
- return connection_get_more_segments_bp(conn);
221
- case CONNECTION_SSL:
222
- return connection_get_more_segments_ssl(conn);
215
+ int io_get_more_segments(struct um_io *io) {
216
+ switch (io->mode) {
217
+ case IO_FD:
218
+ case IO_SOCKET:
219
+ return io_get_more_segments_bp(io);
220
+ case IO_SSL:
221
+ return io_get_more_segments_ssl(io);
223
222
  default:
224
- rb_raise(eUMError, "Invalid connection mode");
223
+ rb_raise(eUMError, "Invalid IO mode");
225
224
  }
226
225
  }
227
226
 
228
227
  ////////////////////////////////////////////////////////////////////////////////
229
228
 
230
- inline void connection_shift_head(struct um_connection *conn) {
231
- struct um_segment *consumed = conn->head;
232
- conn->head = consumed->next;
233
- if (!conn->head) conn->tail = NULL;
234
- um_segment_checkin(conn->machine, consumed);
235
- conn->pos = 0;
229
+ inline void io_shift_head(struct um_io *io) {
230
+ struct um_segment *consumed = io->head;
231
+ io->head = consumed->next;
232
+ if (!io->head) io->tail = NULL;
233
+ um_segment_checkin(io->machine, consumed);
234
+ io->pos = 0;
236
235
  }
237
236
 
238
237
  inline VALUE make_segment_io_buffer(struct um_segment *segment, size_t pos) {
@@ -242,32 +241,32 @@ inline VALUE make_segment_io_buffer(struct um_segment *segment, size_t pos) {
242
241
  );
243
242
  }
244
243
 
245
- inline void connection_skip(struct um_connection *conn, size_t inc, int safe_inc) {
246
- if (unlikely(conn->eof && !conn->head)) return;
247
- if (safe_inc && !conn->tail && !connection_get_more_segments(conn)) return;
244
+ inline void io_skip(struct um_io *io, size_t inc, int safe_inc) {
245
+ if (unlikely(io->eof && !io->head)) return;
246
+ if (safe_inc && !io->tail && !io_get_more_segments(io)) return;
248
247
 
249
248
  while (inc) {
250
- size_t segment_len = conn->head->len - conn->pos;
249
+ size_t segment_len = io->head->len - io->pos;
251
250
  size_t inc_len = (segment_len <= inc) ? segment_len : inc;
252
251
  inc -= inc_len;
253
- conn->pos += inc_len;
254
- conn->consumed_bytes += inc_len;
255
- conn->pending_bytes -= inc_len;
256
- if (conn->pos == conn->head->len) {
257
- connection_shift_head(conn);
258
- if (inc && safe_inc && !conn->head) {
259
- if (!connection_get_more_segments(conn)) break;
252
+ io->pos += inc_len;
253
+ io->consumed_bytes += inc_len;
254
+ io->pending_bytes -= inc_len;
255
+ if (io->pos == io->head->len) {
256
+ io_shift_head(io);
257
+ if (inc && safe_inc && !io->head) {
258
+ if (!io_get_more_segments(io)) break;
260
259
  }
261
260
  }
262
261
  }
263
262
  }
264
263
 
265
- inline void connection_read_each(struct um_connection *conn) {
266
- if (unlikely(conn->eof && !conn->head)) return;
267
- if (!conn->tail && !connection_get_more_segments(conn)) return;
264
+ inline void io_read_each(struct um_io *io) {
265
+ if (unlikely(io->eof && !io->head)) return;
266
+ if (!io->tail && !io_get_more_segments(io)) return;
268
267
 
269
- struct um_segment *current = conn->head;
270
- size_t pos = conn->pos;
268
+ struct um_segment *current = io->head;
269
+ size_t pos = io->pos;
271
270
 
272
271
  VALUE buffer = Qnil;
273
272
  while (true) {
@@ -275,34 +274,34 @@ inline void connection_read_each(struct um_connection *conn) {
275
274
  buffer = make_segment_io_buffer(current, pos);
276
275
  rb_yield(buffer);
277
276
  rb_io_buffer_free_locked(buffer);
278
- connection_shift_head(conn);
277
+ io_shift_head(io);
279
278
 
280
279
  if (!next) {
281
- if (!connection_get_more_segments(conn)) return;
280
+ if (!io_get_more_segments(io)) return;
282
281
  }
283
- current = conn->head;
282
+ current = io->head;
284
283
  pos = 0;
285
284
  }
286
285
  RB_GC_GUARD(buffer);
287
286
  }
288
287
 
289
- inline void connection_copy(struct um_connection *conn, char *dest, size_t len) {
288
+ inline void io_copy(struct um_io *io, char *dest, size_t len) {
290
289
  while (len) {
291
- char *segment_ptr = conn->head->ptr + conn->pos;
292
- size_t segment_len = conn->head->len - conn->pos;
290
+ char *segment_ptr = io->head->ptr + io->pos;
291
+ size_t segment_len = io->head->len - io->pos;
293
292
  size_t cpy_len = (segment_len <= len) ? segment_len : len;
294
293
  memcpy(dest, segment_ptr, cpy_len);
295
294
 
296
295
  len -= cpy_len;
297
- conn->pos += cpy_len;
298
- conn->consumed_bytes += cpy_len;
299
- conn->pending_bytes -= cpy_len;
296
+ io->pos += cpy_len;
297
+ io->consumed_bytes += cpy_len;
298
+ io->pending_bytes -= cpy_len;
300
299
  dest += cpy_len;
301
- if (conn->pos == conn->head->len) connection_shift_head(conn);
300
+ if (io->pos == io->head->len) io_shift_head(io);
302
301
  }
303
302
  }
304
303
 
305
- VALUE connection_consume_string(struct um_connection *conn, VALUE out_buffer, size_t len, size_t inc, int safe_inc) {
304
+ VALUE io_consume_string(struct um_io *io, VALUE out_buffer, size_t len, size_t inc, int safe_inc) {
306
305
  VALUE str = Qnil;
307
306
  if (!NIL_P(out_buffer)) {
308
307
  str = out_buffer;
@@ -316,8 +315,8 @@ VALUE connection_consume_string(struct um_connection *conn, VALUE out_buffer, si
316
315
  str = rb_str_new(NULL, len);
317
316
  char *dest = RSTRING_PTR(str);
318
317
 
319
- connection_copy(conn, dest, len);
320
- connection_skip(conn, inc, safe_inc);
318
+ io_copy(io, dest, len);
319
+ io_skip(io, inc, safe_inc);
321
320
  return str;
322
321
  RB_GC_GUARD(str);
323
322
  }
@@ -326,16 +325,16 @@ inline int trailing_cr_p(char *ptr, size_t len) {
326
325
  return ptr[len - 1] == '\r';
327
326
  }
328
327
 
329
- VALUE connection_read_line(struct um_connection *conn, VALUE out_buffer, size_t maxlen) {
330
- if (unlikely(conn->eof && !conn->head)) return Qnil;
331
- if (!conn->tail && !connection_get_more_segments(conn)) return Qnil;
328
+ VALUE io_read_line(struct um_io *io, VALUE out_buffer, size_t maxlen) {
329
+ if (unlikely(io->eof && !io->head)) return Qnil;
330
+ if (!io->tail && !io_get_more_segments(io)) return Qnil;
332
331
 
333
332
  struct um_segment *last = NULL;
334
- struct um_segment *current = conn->head;
333
+ struct um_segment *current = io->head;
335
334
  size_t remaining_len = maxlen;
336
335
  size_t total_len = 0;
337
336
  size_t inc = 1;
338
- size_t pos = conn->pos;
337
+ size_t pos = io->pos;
339
338
 
340
339
  while (true) {
341
340
  size_t segment_len = current->len - pos;
@@ -359,7 +358,7 @@ VALUE connection_read_line(struct um_connection *conn, VALUE out_buffer, size_t
359
358
  }
360
359
  }
361
360
 
362
- return connection_consume_string(conn, out_buffer, total_len, inc, false);
361
+ return io_consume_string(io, out_buffer, total_len, inc, false);
363
362
  }
364
363
  else {
365
364
  // not found, early return if segment len exceeds maxlen
@@ -370,7 +369,7 @@ VALUE connection_read_line(struct um_connection *conn, VALUE out_buffer, size_t
370
369
  }
371
370
 
372
371
  if (!current->next) {
373
- if (!connection_get_more_segments(conn)) {
372
+ if (!io_get_more_segments(io)) {
374
373
  return Qnil;
375
374
  }
376
375
  }
@@ -381,15 +380,15 @@ VALUE connection_read_line(struct um_connection *conn, VALUE out_buffer, size_t
381
380
  }
382
381
  }
383
382
 
384
- VALUE connection_read(struct um_connection *conn, VALUE out_buffer, ssize_t len, size_t inc, int safe_inc) {
385
- if (unlikely(conn->eof && !conn->head)) return Qnil;
386
- if (!conn->tail && !connection_get_more_segments(conn)) return Qnil;
383
+ VALUE io_read(struct um_io *io, VALUE out_buffer, ssize_t len, size_t inc, int safe_inc) {
384
+ if (unlikely(io->eof && !io->head)) return Qnil;
385
+ if (!io->tail && !io_get_more_segments(io)) return Qnil;
387
386
 
388
- struct um_segment *current = conn->head;
387
+ struct um_segment *current = io->head;
389
388
  size_t abs_len = labs(len);
390
389
  size_t remaining_len = abs_len;
391
390
  size_t total_len = 0;
392
- size_t pos = conn->pos;
391
+ size_t pos = io->pos;
393
392
 
394
393
  while (true) {
395
394
  size_t segment_len = current->len - pos;
@@ -400,14 +399,14 @@ VALUE connection_read(struct um_connection *conn, VALUE out_buffer, ssize_t len,
400
399
  if (abs_len) {
401
400
  remaining_len -= segment_len;
402
401
  if (!remaining_len)
403
- return connection_consume_string(conn, out_buffer, total_len, inc, safe_inc);
402
+ return io_consume_string(io, out_buffer, total_len, inc, safe_inc);
404
403
  }
405
404
 
406
405
  if (!current->next) {
407
406
  if (len <= 0)
408
- return connection_consume_string(conn, out_buffer, total_len, inc, safe_inc);
407
+ return io_consume_string(io, out_buffer, total_len, inc, safe_inc);
409
408
 
410
- if (!connection_get_more_segments(conn))
409
+ if (!io_get_more_segments(io))
411
410
  return Qnil;
412
411
  }
413
412
  current = current->next;
@@ -425,17 +424,17 @@ static inline char delim_to_char(VALUE delim) {
425
424
  return *RSTRING_PTR(delim);
426
425
  }
427
426
 
428
- VALUE connection_read_to_delim(struct um_connection *conn, VALUE out_buffer, VALUE delim, ssize_t maxlen) {
427
+ VALUE io_read_to_delim(struct um_io *io, VALUE out_buffer, VALUE delim, ssize_t maxlen) {
429
428
  char delim_char = delim_to_char(delim);
430
429
 
431
- if (unlikely(conn->eof && !conn->head)) return Qnil;
432
- if (unlikely(!conn->tail) && !connection_get_more_segments(conn)) return Qnil;
430
+ if (unlikely(io->eof && !io->head)) return Qnil;
431
+ if (unlikely(!io->tail) && !io_get_more_segments(io)) return Qnil;
433
432
 
434
- struct um_segment *current = conn->head;
433
+ struct um_segment *current = io->head;
435
434
  size_t abs_maxlen = labs(maxlen);
436
435
  size_t remaining_len = abs_maxlen;
437
436
  size_t total_len = 0;
438
- size_t pos = conn->pos;
437
+ size_t pos = io->pos;
439
438
 
440
439
  while (true) {
441
440
  size_t segment_len = current->len - pos;
@@ -447,7 +446,7 @@ VALUE connection_read_to_delim(struct um_connection *conn, VALUE out_buffer, VAL
447
446
  if (delim_ptr) {
448
447
  size_t len = delim_ptr - start;
449
448
  total_len += len;
450
- return connection_consume_string(conn, out_buffer, total_len, 1, false);
449
+ return io_consume_string(io, out_buffer, total_len, 1, false);
451
450
  }
452
451
  else {
453
452
  // delimiter not found
@@ -455,51 +454,51 @@ VALUE connection_read_to_delim(struct um_connection *conn, VALUE out_buffer, VAL
455
454
  remaining_len -= search_len;
456
455
 
457
456
  if (abs_maxlen && total_len >= abs_maxlen)
458
- return (maxlen > 0) ? Qnil : connection_consume_string(conn, out_buffer, abs_maxlen, 1, false);
457
+ return (maxlen > 0) ? Qnil : io_consume_string(io, out_buffer, abs_maxlen, 1, false);
459
458
  }
460
459
 
461
- if (!current->next && !connection_get_more_segments(conn)) return Qnil;
460
+ if (!current->next && !io_get_more_segments(io)) return Qnil;
462
461
 
463
462
  current = current->next;
464
463
  pos = 0;
465
464
  }
466
465
  }
467
466
 
468
- size_t connection_write_raw(struct um_connection *conn, const char *buffer, size_t len) {
469
- switch (conn->mode) {
470
- case CONNECTION_FD:
471
- return um_write_raw(conn->machine, conn->fd, buffer, len);
472
- case CONNECTION_SOCKET:
473
- return um_send_raw(conn->machine, conn->fd, buffer, len, 0);
474
- case CONNECTION_SSL:
475
- return um_ssl_write_raw(conn->machine, conn->target, buffer, len);
467
+ size_t io_write_raw(struct um_io *io, const char *buffer, size_t len) {
468
+ switch (io->mode) {
469
+ case IO_FD:
470
+ return um_write_raw(io->machine, io->fd, buffer, len);
471
+ case IO_SOCKET:
472
+ return um_send_raw(io->machine, io->fd, buffer, len, 0);
473
+ case IO_SSL:
474
+ return um_ssl_write_raw(io->machine, io->target, buffer, len);
476
475
  default:
477
- rb_raise(eUMError, "Invalid connection mode");
476
+ rb_raise(eUMError, "Invalid IO mode");
478
477
  }
479
478
  }
480
479
 
481
- VALUE connection_writev(struct um_connection *conn, int argc, VALUE *argv) {
482
- switch (conn->mode) {
483
- case CONNECTION_FD:
484
- return um_writev(conn->machine, conn->fd, argc, argv);
485
- case CONNECTION_SOCKET:
486
- return um_sendv(conn->machine, conn->fd, argc, argv);
487
- case CONNECTION_SSL:
488
- return ULONG2NUM(um_ssl_writev(conn->machine, conn->target, argc, argv));
480
+ VALUE io_writev(struct um_io *io, int argc, VALUE *argv) {
481
+ switch (io->mode) {
482
+ case IO_FD:
483
+ return um_writev(io->machine, io->fd, argc, argv);
484
+ case IO_SOCKET:
485
+ return um_sendv(io->machine, io->fd, argc, argv);
486
+ case IO_SSL:
487
+ return ULONG2NUM(um_ssl_writev(io->machine, io->target, argc, argv));
489
488
  default:
490
- rb_raise(eUMError, "Invalid connection mode");
489
+ rb_raise(eUMError, "Invalid IO mode");
491
490
  }
492
491
  }
493
492
 
494
493
  ////////////////////////////////////////////////////////////////////////////////
495
494
 
496
- VALUE resp_read_line(struct um_connection *conn, VALUE out_buffer) {
497
- if (unlikely(conn->eof && !conn->head)) return Qnil;
498
- if (!conn->tail && !connection_get_more_segments(conn)) return Qnil;
495
+ VALUE resp_read_line(struct um_io *io, VALUE out_buffer) {
496
+ if (unlikely(io->eof && !io->head)) return Qnil;
497
+ if (!io->tail && !io_get_more_segments(io)) return Qnil;
499
498
 
500
- struct um_segment *current = conn->head;
499
+ struct um_segment *current = io->head;
501
500
  size_t total_len = 0;
502
- size_t pos = conn->pos;
501
+ size_t pos = io->pos;
503
502
 
504
503
  while (true) {
505
504
  size_t segment_len = current->len - pos;
@@ -508,20 +507,20 @@ VALUE resp_read_line(struct um_connection *conn, VALUE out_buffer) {
508
507
  if (lf_ptr) {
509
508
  size_t len = lf_ptr - start;
510
509
  total_len += len;
511
- return connection_consume_string(conn, out_buffer, total_len, 2, true);
510
+ return io_consume_string(io, out_buffer, total_len, 2, true);
512
511
  }
513
512
  else
514
513
  total_len += segment_len;
515
514
 
516
515
  if (!current->next)
517
- if (!connection_get_more_segments(conn)) return Qnil;
516
+ if (!io_get_more_segments(io)) return Qnil;
518
517
 
519
518
  current = current->next;
520
519
  }
521
520
  }
522
521
 
523
- inline VALUE resp_read_string(struct um_connection *conn, ulong len, VALUE out_buffer) {
524
- return connection_read(conn, out_buffer, len, 2, true);
522
+ inline VALUE resp_read_string(struct um_io *io, ulong len, VALUE out_buffer) {
523
+ return io_read(io, out_buffer, len, 2, true);
525
524
  }
526
525
 
527
526
  inline ulong resp_parse_length_field(const char *ptr, int len) {
@@ -531,12 +530,12 @@ inline ulong resp_parse_length_field(const char *ptr, int len) {
531
530
  return acc;
532
531
  }
533
532
 
534
- VALUE resp_decode_hash(struct um_connection *conn, VALUE out_buffer, ulong len) {
533
+ VALUE resp_decode_hash(struct um_io *io, VALUE out_buffer, ulong len) {
535
534
  VALUE hash = rb_hash_new();
536
535
 
537
536
  for (ulong i = 0; i < len; i++) {
538
- VALUE key = resp_read(conn, out_buffer);
539
- VALUE value = resp_read(conn, out_buffer);
537
+ VALUE key = resp_read(io, out_buffer);
538
+ VALUE value = resp_read(io, out_buffer);
540
539
  rb_hash_aset(hash, key, value);
541
540
  RB_GC_GUARD(key);
542
541
  RB_GC_GUARD(value);
@@ -546,11 +545,11 @@ VALUE resp_decode_hash(struct um_connection *conn, VALUE out_buffer, ulong len)
546
545
  return hash;
547
546
  }
548
547
 
549
- VALUE resp_decode_array(struct um_connection *conn, VALUE out_buffer, ulong len) {
548
+ VALUE resp_decode_array(struct um_io *io, VALUE out_buffer, ulong len) {
550
549
  VALUE array = rb_ary_new2(len);
551
550
 
552
551
  for (ulong i = 0; i < len; i++) {
553
- VALUE value = resp_read(conn, out_buffer);
552
+ VALUE value = resp_read(io, out_buffer);
554
553
  rb_ary_push(array, value);
555
554
  RB_GC_GUARD(value);
556
555
  }
@@ -563,12 +562,12 @@ static inline VALUE resp_decode_simple_string(char *ptr, ulong len) {
563
562
  return rb_str_new(ptr + 1, len - 1);
564
563
  }
565
564
 
566
- static inline VALUE resp_decode_string(struct um_connection *conn, VALUE out_buffer, ulong len) {
567
- return resp_read_string(conn, len, out_buffer);
565
+ static inline VALUE resp_decode_string(struct um_io *io, VALUE out_buffer, ulong len) {
566
+ return resp_read_string(io, len, out_buffer);
568
567
  }
569
568
 
570
- static inline VALUE resp_decode_string_with_encoding(struct um_connection *conn, VALUE out_buffer, ulong len) {
571
- VALUE with_enc = resp_read_string(conn, len, out_buffer);
569
+ static inline VALUE resp_decode_string_with_encoding(struct um_io *io, VALUE out_buffer, ulong len) {
570
+ VALUE with_enc = resp_read_string(io, len, out_buffer);
572
571
  char *ptr = RSTRING_PTR(with_enc);
573
572
  len = RSTRING_LEN(with_enc);
574
573
  if ((len < 4) || (ptr[3] != ':')) return Qnil;
@@ -591,23 +590,23 @@ static inline VALUE resp_decode_simple_error(char *ptr, ulong len) {
591
590
  if (!ID_new) ID_new = rb_intern("new");
592
591
 
593
592
  VALUE msg = rb_str_new(ptr + 1, len - 1);
594
- VALUE err = rb_funcall(eConnectionRESPError, ID_new, 1, msg);
593
+ VALUE err = rb_funcall(eIORESPError, ID_new, 1, msg);
595
594
  RB_GC_GUARD(msg);
596
595
  return err;
597
596
  }
598
597
 
599
- static inline VALUE resp_decode_error(struct um_connection *conn, VALUE out_buffer, ulong len) {
598
+ static inline VALUE resp_decode_error(struct um_io *io, VALUE out_buffer, ulong len) {
600
599
  static ID ID_new = 0;
601
600
  if (!ID_new) ID_new = rb_intern("new");
602
601
 
603
- VALUE msg = resp_decode_string(conn, out_buffer, len);
604
- VALUE err = rb_funcall(eConnectionRESPError, ID_new, 1, msg);
602
+ VALUE msg = resp_decode_string(io, out_buffer, len);
603
+ VALUE err = rb_funcall(eIORESPError, ID_new, 1, msg);
605
604
  RB_GC_GUARD(msg);
606
605
  return err;
607
606
  }
608
607
 
609
- VALUE resp_read(struct um_connection *conn, VALUE out_buffer) {
610
- VALUE msg = resp_read_line(conn, out_buffer);
608
+ VALUE resp_read(struct um_io *io, VALUE out_buffer) {
609
+ VALUE msg = resp_read_line(io, out_buffer);
611
610
  if (msg == Qnil) return Qnil;
612
611
 
613
612
  char *ptr = RSTRING_PTR(msg);
@@ -619,22 +618,22 @@ VALUE resp_read(struct um_connection *conn, VALUE out_buffer) {
619
618
  case '%': // hash
620
619
  case '|': // attributes hash
621
620
  data_len = resp_parse_length_field(ptr, len);
622
- return resp_decode_hash(conn, out_buffer, data_len);
621
+ return resp_decode_hash(io, out_buffer, data_len);
623
622
 
624
623
  case '*': // array
625
624
  case '~': // set
626
625
  case '>': // pub/sub push
627
626
  data_len = resp_parse_length_field(ptr, len);
628
- return resp_decode_array(conn, out_buffer, data_len);
627
+ return resp_decode_array(io, out_buffer, data_len);
629
628
 
630
629
  case '+': // simple string
631
630
  return resp_decode_simple_string(ptr, len);
632
631
  case '$': // string
633
632
  data_len = resp_parse_length_field(ptr, len);
634
- return resp_decode_string(conn, out_buffer, data_len);
633
+ return resp_decode_string(io, out_buffer, data_len);
635
634
  case '=': // string with encoding
636
635
  data_len = resp_parse_length_field(ptr, len);
637
- return resp_decode_string_with_encoding(conn, out_buffer, data_len);
636
+ return resp_decode_string_with_encoding(io, out_buffer, data_len);
638
637
 
639
638
  case '_': // null
640
639
  return Qnil;
@@ -652,7 +651,7 @@ VALUE resp_read(struct um_connection *conn, VALUE out_buffer) {
652
651
  return resp_decode_simple_error(ptr, len);
653
652
  case '!': // error
654
653
  data_len = resp_parse_length_field(ptr, len);
655
- return resp_decode_error(conn, out_buffer, data_len);
654
+ return resp_decode_error(io, out_buffer, data_len);
656
655
  default:
657
656
  um_raise_internal_error("Invalid character encountered");
658
657
  }