1
1
#include <sys/wait.h>
2
+ #include <poll.h>
2
3
#include "common.h"
3
4
#include "sstring.h"
4
5
#include "executor.h"
@@ -75,46 +76,45 @@ fork_command(struct slot *pslot, void (*fn)(struct slot *, int, char **), int ar
75
76
}
76
77
77
78
static void
78
- fdset_alive_slots (struct slot * pslot , fd_set * readfds ) {
79
+ poll_alive_slots (struct slot * pslot , struct pollfd * pfd , size_t * cnt ) {
80
+ * cnt = 0 ;
79
81
while (pslot ) {
80
82
if (!pslot -> alive ) {
83
+ pslot -> poll_index = -1 ;
81
84
pslot = pslot -> next ;
82
85
continue ;
83
86
}
84
- FD_SET (pslot -> io .out [PIPE_READ_END ], readfds );
85
- FD_SET (pslot -> io .err [PIPE_READ_END ], readfds );
87
+ pslot -> poll_index = (int ) * cnt ;
88
+
89
+ pfd [* cnt ].fd = pslot -> io .out [PIPE_READ_END ];
90
+ pfd [* cnt ].events = POLLIN ;
91
+ * cnt = * cnt + 1 ;
92
+
93
+ pfd [* cnt ].fd = pslot -> io .err [PIPE_READ_END ];
94
+ pfd [* cnt ].events = POLLIN ;
95
+ * cnt = * cnt + 1 ;
96
+
86
97
pslot = pslot -> next ;
87
98
}
88
99
}
89
100
90
101
static void
91
- read_alive_slots (struct slot * pslot , fd_set * readfds , FILE * output ) {
102
+ read_alive_slots (struct slot * pslot , struct pollfd * pfd , FILE * output ) {
92
103
while (pslot ) {
93
- if (!pslot -> alive ) {
104
+ if (!pslot -> alive || pslot -> poll_index < 0 ) {
94
105
pslot = pslot -> next ;
95
106
continue ;
96
107
}
97
- if (FD_ISSET ( pslot -> io . out [ PIPE_READ_END ], readfds ) ) {
108
+ if (pfd [ pslot -> poll_index ]. revents & POLLIN ) {
98
109
slot_read_line (pslot , STDOUT_FILENO , print_line , output );
99
110
}
100
- if (FD_ISSET ( pslot -> io . err [ PIPE_READ_END ], readfds ) ) {
111
+ if (pfd [ pslot -> poll_index + 1 ]. revents & POLLIN ) {
101
112
slot_read_line (pslot , STDERR_FILENO , print_line , output );
102
113
}
103
114
pslot = pslot -> next ;
104
115
}
105
116
}
106
117
107
- static void
108
- read_dead_slots (struct slot * pslot , struct slot * pslot_end , FILE * output ) {
109
- while (pslot && pslot != pslot_end ) {
110
- if (!pslot -> alive ) {
111
- slot_read_remains (pslot , STDOUT_FILENO , print_line , output );
112
- slot_read_remains (pslot , STDERR_FILENO , print_line , output );
113
- }
114
- pslot = pslot -> next ;
115
- }
116
- }
117
-
118
118
int
119
119
exec_local_cmd (char * cmd ) {
120
120
return system (cmd );
@@ -177,9 +177,12 @@ reap_child_handler(int sig) {
177
177
else
178
178
exit_code = 255 ;
179
179
pslot = slot_find_by_pid (slots , pid );
180
- if (pslot ) {
181
- slot_close ( pslot , exit_code ) ;
180
+ if (! pslot ) {
181
+ continue ;
182
182
}
183
+ slot_read_remains (pslot , STDOUT_FILENO , print_line , pslot -> output );
184
+ slot_read_remains (pslot , STDERR_FILENO , print_line , pslot -> output );
185
+ slot_close (pslot , exit_code );
183
186
if (pconfig -> verbose ) {
184
187
printf ("wait pid %d, status code %d\n" , pslot -> pid , pslot -> exit_code );
185
188
}
@@ -314,19 +317,17 @@ exec_scp_cmd(struct slot *pslot, int argc, char **argv) {
314
317
315
318
static int
316
319
exec_command_foreach (struct slot * pslot_list , void (* fn_fork )(struct slot * , int , char * * ), int argc , char * * argv ) {
317
- fd_set readfds ;
318
- struct slot * pslot = pslot_list -> next ;
319
- struct slot * pslot_head = pslot ;
320
- struct timeval no_timeout ;
321
- struct timeval * timeout ;
320
+ struct pollfd * pfd ;
321
+ struct slot * pslot_head = pslot_list -> next ;
322
+ struct slot * pslot = pslot_head ;
323
+ int timeout ;
322
324
FILE * output ;
325
+ size_t cnt = 0 ;
323
326
324
- if (!pslot ) {
327
+ if (!pslot ) {
325
328
return 0 ;
326
329
}
327
330
328
- memset (& no_timeout , 0 , sizeof (struct timeval ));
329
-
330
331
if (pconfig -> output_file ) {
331
332
output = fopen (pconfig -> output_file , "a" );
332
333
if (!output ) {
@@ -337,6 +338,15 @@ exec_command_foreach(struct slot *pslot_list, void (*fn_fork)(struct slot *, int
337
338
output = stdout ;
338
339
}
339
340
341
+ while (pslot ) {
342
+ // poll stdout & stderr
343
+ cnt += 2 ;
344
+ pslot -> output = output ;
345
+ pslot = pslot -> next ;
346
+ }
347
+ pfd = calloc (cnt , sizeof (struct pollfd ));
348
+ pslot = pslot_head ;
349
+
340
350
alive_children = 0 ;
341
351
342
352
while (pslot || alive_children ) {
@@ -347,25 +357,21 @@ exec_command_foreach(struct slot *pslot_list, void (*fn_fork)(struct slot *, int
347
357
usleep (10 * 1000 );
348
358
}
349
359
350
- read_dead_slots (pslot_head , pslot , output );
351
-
352
- FD_ZERO (& readfds );
353
- fdset_alive_slots (pslot_head , & readfds );
360
+ poll_alive_slots (pslot_head , pfd , & cnt );
354
361
355
- timeout = pslot ? & no_timeout : NULL ;
362
+ timeout = pslot ? 0 : -1 ;
356
363
357
- if (select ( MAXFD , & readfds , NULL , NULL , timeout ) > 0 ) {
358
- read_alive_slots (pslot_head , & readfds , output );
364
+ if (poll ( pfd , ( nfds_t ) cnt , timeout ) > 0 ) {
365
+ read_alive_slots (pslot_head , pfd , output );
359
366
}
360
367
UNBLOCK_SIGCHLD ;
361
368
}
362
369
363
- read_dead_slots (pslot_head , pslot , output );
364
-
365
370
if (output != stdout ) {
366
371
fclose (output );
367
372
}
368
373
374
+ free (pfd );
369
375
return 0 ;
370
376
}
371
377
@@ -392,30 +398,34 @@ download_file(struct slot *pslot_list, char *remote_filename, char *local_filena
392
398
393
399
int
394
400
sync_exec_remote_cmd (struct slot * pslot_list , char * cmd , sstring * out , sstring * err ) {
395
-
396
- fd_set readfds ;
401
+ struct pollfd pfd [2 ];
397
402
char * argv [1 ] = {cmd };
398
403
struct slot * pslot = pslot_list -> next ;
399
404
400
405
if (!pslot ) {
401
406
return 0 ;
402
407
}
403
408
404
- FD_ZERO (& readfds );
409
+ memset (& pfd [0 ], 0 , sizeof (struct pollfd ));
410
+ memset (& pfd [1 ], 0 , sizeof (struct pollfd ));
411
+
412
+ alive_children = 0 ;
405
413
406
414
BLOCK_SIGCHLD ;
407
415
fork_command (pslot , exec_ssh_cmd , 1 , argv );
408
- FD_SET (pslot -> io .out [PIPE_READ_END ], & readfds );
409
- FD_SET (pslot -> io .err [PIPE_READ_END ], & readfds );
416
+ pfd [0 ].fd = pslot -> io .out [PIPE_READ_END ];
417
+ pfd [0 ].events = POLLIN ;
418
+ pfd [1 ].fd = pslot -> io .err [PIPE_READ_END ];
419
+ pfd [1 ].events = POLLIN ;
410
420
UNBLOCK_SIGCHLD ;
411
421
412
422
while (alive_children ) {
413
423
BLOCK_SIGCHLD ;
414
- if (select ( MAXFD , & readfds , NULL , NULL , NULL ) > 0 ) {
415
- if (FD_ISSET ( pslot -> io . out [ PIPE_READ_END ], & readfds ) ) {
424
+ if (poll ( pfd , 2 , 0 ) > 0 ) {
425
+ if (pfd [ 0 ]. revents & POLLIN ) {
416
426
slot_read_line (pslot , STDOUT_FILENO , save_string , out );
417
427
}
418
- if (FD_ISSET ( pslot -> io . err [ PIPE_READ_END ], & readfds ) ) {
428
+ if (pfd [ 1 ]. revents & POLLIN ) {
419
429
slot_read_line (pslot , STDERR_FILENO , save_string , err );
420
430
}
421
431
}
0 commit comments