1
2 #include "processx.h"
3
processx_poll(SEXP statuses,SEXP types,SEXP ms)4 SEXP processx_poll(SEXP statuses, SEXP types, SEXP ms) {
5 int cms = INTEGER(ms)[0];
6 int i, j, num_total = LENGTH(statuses);
7 processx_pollable_t *pollables;
8 SEXP result;
9 int num_proc = 0, num_poll;
10
11 for (i = 0; i < num_total; i++) if (INTEGER(types)[i] == 1) num_proc++;
12 num_poll = num_total + num_proc * 2;
13
14 pollables = (processx_pollable_t*)
15 R_alloc(num_poll, sizeof(processx_pollable_t));
16
17 result = PROTECT(allocVector(VECSXP, num_total));
18 for (i = 0, j = 0; i < num_total; i++) {
19 SEXP status = VECTOR_ELT(statuses, i);
20 if (INTEGER(types)[i] == 1) {
21 SEXP process = VECTOR_ELT(status, 0);
22 SEXP pollconn = VECTOR_ELT(status, 1);
23 processx_handle_t *handle = R_ExternalPtrAddr(process);
24 processx_connection_t *cpollconn = isNull(pollconn) ? 0 :
25 R_ExternalPtrAddr(pollconn);
26
27 processx_c_pollable_from_connection(&pollables[j], handle->pipes[1]);
28 if (handle->pipes[1]) handle->pipes[1]->poll_idx = j;
29 j++;
30 processx_c_pollable_from_connection(&pollables[j], handle->pipes[2]);
31 if (handle->pipes[2]) handle->pipes[2]->poll_idx = j;
32 j++;
33
34 processx_c_pollable_from_connection(&pollables[j], cpollconn);
35 if (cpollconn) cpollconn->poll_idx = j;
36 j++;
37
38 SET_VECTOR_ELT(result, i, allocVector(INTSXP, 3));
39
40 } else if (INTEGER(types)[i] == 2) {
41 processx_connection_t *handle = R_ExternalPtrAddr(status);
42 processx_c_pollable_from_connection(&pollables[j], handle);
43 if (handle) handle->poll_idx = j;
44 j++;
45 SET_VECTOR_ELT(result, i, allocVector(INTSXP, 1));
46
47 } else if (INTEGER(types)[i] == 3) {
48 processx_c_pollable_from_curl(&pollables[j], status);
49 j++;
50 SET_VECTOR_ELT(result, i, allocVector(INTSXP, 1));
51 }
52 }
53
54 processx_c_connection_poll(pollables, num_poll, cms);
55
56 for (i = 0, j = 0; i < num_total; i++) {
57 if (INTEGER(types)[i] == 1) {
58 INTEGER(VECTOR_ELT(result, i))[0] = pollables[j++].event;
59 INTEGER(VECTOR_ELT(result, i))[1] = pollables[j++].event;
60 INTEGER(VECTOR_ELT(result, i))[2] = pollables[j++].event;
61 } else if (INTEGER(types)[i] == 2) {
62 INTEGER(VECTOR_ELT(result, i))[0] = pollables[j++].event;
63 } else {
64 INTEGER(VECTOR_ELT(result, i))[0] = pollables[j++].event;
65 }
66 }
67
68 UNPROTECT(1);
69 return result;
70 }
71