@@ -15,9 +15,12 @@ struct connect_data {
15
15
chan_handle chan;
16
16
};
17
17
18
+ const intptr_t whatever_tag = 0 ;
18
19
const intptr_t connected_tag = 1 ;
19
20
const intptr_t wrote_tag = 2 ;
20
21
const intptr_t read_tag = 3 ;
22
+ const intptr_t timer_tag = 4 ;
23
+ const intptr_t exit_tag = 5 ;
21
24
22
25
struct iomsg {
23
26
intptr_t tag;
@@ -29,6 +32,7 @@ struct iomsg {
29
32
uint8_t *buf;
30
33
ssize_t nread;
31
34
} read_val;
35
+ uint32_t timer_req_id;
32
36
} val;
33
37
};
34
38
@@ -44,6 +48,13 @@ struct read_start_data {
44
48
chan_handle chan;
45
49
};
46
50
51
+ struct timer_start_data {
52
+ rust_uvtmp_thread *thread;
53
+ uint32_t timeout;
54
+ uint32_t req_id;
55
+ chan_handle chan;
56
+ };
57
+
47
58
// FIXME: Copied from rust_builtins.cpp. Could bitrot easily
48
59
static void
49
60
send (rust_task *task, chan_handle chan, void *data) {
@@ -72,7 +83,7 @@ class rust_uvtmp_thread : public rust_thread {
72
83
std::queue<connect_data*> close_connection_queue;
73
84
std::queue<write_data*> write_queue;
74
85
std::queue<read_start_data*> read_start_queue;
75
-
86
+ std::queue<timer_start_data*> timer_start_queue;
76
87
public:
77
88
78
89
rust_uvtmp_thread () {
@@ -139,6 +150,17 @@ class rust_uvtmp_thread : public rust_thread {
139
150
read_start_queue.push (rd);
140
151
}
141
152
153
+ void
154
+ timer (uint32_t timeout, uint32_t req_id, chan_handle chan) {
155
+ scoped_lock with (lock);
156
+
157
+ timer_start_data *td = new timer_start_data ();
158
+ td->timeout = timeout;
159
+ td->req_id = req_id;
160
+ td->chan = chan;
161
+ timer_start_queue.push (td);
162
+ }
163
+
142
164
private:
143
165
144
166
virtual void
@@ -159,6 +181,7 @@ class rust_uvtmp_thread : public rust_thread {
159
181
close_connections ();
160
182
write_buffers ();
161
183
start_reads ();
184
+ start_timers ();
162
185
close_idle_if_stop ();
163
186
}
164
187
@@ -246,7 +269,7 @@ class rust_uvtmp_thread : public rust_thread {
246
269
void
247
270
on_write (uv_write_t *handle, write_data *wd) {
248
271
iomsg msg;
249
- msg.tag = wrote_tag ;
272
+ msg.tag = timer_tag ;
250
273
msg.val .wrote_val = wd->cd ;
251
274
252
275
send (task, wd->chan , &msg);
@@ -299,6 +322,40 @@ class rust_uvtmp_thread : public rust_thread {
299
322
}
300
323
}
301
324
325
+ void
326
+ start_timers () {
327
+ assert (lock.lock_held_by_current_thread ());
328
+ while (!timer_start_queue.empty ()) {
329
+ timer_start_data *td = timer_start_queue.front ();
330
+ timer_start_queue.pop ();
331
+
332
+ td->thread = this ;
333
+
334
+ uv_timer_t *timer = (uv_timer_t *)malloc (sizeof (uv_timer_t ));
335
+ timer->data = td;
336
+ int result = uv_timer_init (loop, timer);
337
+ result = uv_timer_start (timer, timer_cb, td->timeout , 0 );
338
+ }
339
+ }
340
+
341
+ static void
342
+ timer_cb (uv_timer_t *handle, int what) {
343
+ timer_start_data *td = (timer_start_data*)handle->data ;
344
+ rust_uvtmp_thread *self = td->thread ;
345
+ self->on_timer (td);
346
+ free (handle);
347
+ }
348
+
349
+ void
350
+ on_timer (timer_start_data *rd) {
351
+ iomsg msg;
352
+ msg.tag = timer_tag;
353
+ msg.val .timer_req_id = rd->req_id ;
354
+
355
+ send (task, rd->chan , &msg);
356
+ delete rd;
357
+ }
358
+
302
359
void
303
360
close_idle_if_stop () {
304
361
assert (lock.lock_held_by_current_thread ());
@@ -353,6 +410,11 @@ rust_uvtmp_read_start(rust_uvtmp_thread *thread, uint32_t req_id,
353
410
thread->read_start (req_id, *chan);
354
411
}
355
412
413
+ extern " C" void
414
+ rust_uvtmp_timer (rust_uvtmp_thread *thread, uint32_t timeout, uint32_t req_id, chan_handle *chan) {
415
+ thread->timer (timeout, req_id, *chan);
416
+ }
417
+
356
418
extern " C" void
357
419
rust_uvtmp_delete_buf (uint8_t *buf) {
358
420
delete [] buf;
0 commit comments