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