| | 119 | static |
| | 120 | bool |
| | 121 | wait_child( |
| | 122 | pid_t pid) |
| | 123 | { |
| | 124 | pid_t ret; |
| | 125 | int i; |
| | 126 | |
| | 127 | if (pid == -1) |
| | 128 | { |
| | 129 | fprintf(stderr, "Can't wait for pid -1\n"); |
| | 130 | return false; |
| | 131 | } |
| | 132 | |
| | 133 | for (i = 0; i < WAIT_ZOMBIE_TIMEOUT / WAIT_STEP; i++) |
| | 134 | { |
| | 135 | //printf("waitpid(%d): %d\n", (int)pid, i); |
| | 136 | |
| | 137 | ret = waitpid(pid, NULL, WNOHANG); |
| | 138 | if (ret != 0) |
| | 139 | { |
| | 140 | if (ret == pid) |
| | 141 | { |
| | 142 | //printf("child zombie with pid %d was consumed.\n", (int)pid); |
| | 143 | return true; |
| | 144 | } |
| | 145 | |
| | 146 | if (ret == -1) |
| | 147 | { |
| | 148 | fprintf(stderr, "waitpid(%d) failed: %s\n", (int)pid, strerror(errno)); |
| | 149 | return false; |
| | 150 | } |
| | 151 | |
| | 152 | fprintf(stderr, "we have waited for child pid %d to exit but we got pid %d instead\n", (int)pid, (int)ret); |
| | 153 | |
| | 154 | return false; |
| | 155 | } |
| | 156 | |
| | 157 | //printf("zombie wait %d ms ...\n", WAIT_STEP); |
| | 158 | usleep(WAIT_STEP * 1000); /* wait 100 ms */ |
| | 159 | } |
| | 160 | |
| | 161 | fprintf( |
| | 162 | stderr, |
| | 163 | "we have waited for child with pid %d to exit for %.1f seconds and we are giving up\n", |
| | 164 | (int)pid, |
| | 165 | (float)((float)WAIT_START_TIMEOUT / 1000)); |
| | 166 | |
| | 167 | return false; |
| | 168 | } |
| | 169 | |
| 166 | | /* wait tree seconds for child to exit, we dont like zombie processes */ |
| 167 | | for (i = 0; i < 30; i++) |
| 168 | | { |
| 169 | | //fprintf(stderr, "waitpid(%d): %d\n", (int)control_ptr->pid, i); |
| 170 | | |
| 171 | | ret = waitpid(control_ptr->pid, NULL, WNOHANG); |
| 172 | | if (ret != 0) |
| | 218 | /* for a while wait child to exit, we dont like zombie processes */ |
| | 219 | if (!wait_child(control_ptr->pid)) |
| | 220 | { |
| | 221 | fprintf(stderr, "force killing misbehaved child %d (exit)\n", (int)control_ptr->pid); |
| | 222 | if (kill(control_ptr->pid, SIGKILL) == -1) |
| 433 | | *widget = (LV2UI_Widget)control_ptr; |
| 434 | | |
| 435 | | return (LV2UI_Handle)control_ptr; |
| | 468 | /* wait a while for child process to confirm it is alive */ |
| | 469 | //printf("waiting UI start\n"); |
| | 470 | i = 0; |
| | 471 | loop: |
| | 472 | ret = read(control_ptr->recv_pipe, &ch, 1); |
| | 473 | switch (ret) |
| | 474 | { |
| | 475 | case -1: |
| | 476 | if (errno == EAGAIN) |
| | 477 | { |
| | 478 | if (i < WAIT_START_TIMEOUT / WAIT_STEP) |
| | 479 | { |
| | 480 | //printf("start wait %d ms ...\n", WAIT_STEP); |
| | 481 | usleep(WAIT_STEP * 1000); |
| | 482 | i++; |
| | 483 | goto loop; |
| | 484 | } |
| | 485 | |
| | 486 | fprintf( |
| | 487 | stderr, |
| | 488 | "we have waited for child with pid %d to appear for %.1f seconds and we are giving up\n", |
| | 489 | (int)control_ptr->pid, |
| | 490 | (float)((float)WAIT_START_TIMEOUT / 1000)); |
| | 491 | } |
| | 492 | else |
| | 493 | { |
| | 494 | fprintf(stderr, "read() failed: %s\n", strerror(errno)); |
| | 495 | } |
| | 496 | break; |
| | 497 | case 1: |
| | 498 | if (ch == '\n') |
| | 499 | { |
| | 500 | *widget = (LV2UI_Widget)control_ptr; |
| | 501 | return (LV2UI_Handle)control_ptr; |
| | 502 | } |
| | 503 | |
| | 504 | fprintf(stderr, "read() wrong first char '%c'\n", ch); |
| | 505 | |
| | 506 | break; |
| | 507 | default: |
| | 508 | fprintf(stderr, "read() returned %d\n", ret); |
| | 509 | } |
| | 510 | |
| | 511 | fprintf(stderr, "force killing misbehaved child %d (start)\n", (int)control_ptr->pid); |
| | 512 | |
| | 513 | if (kill(control_ptr->pid, SIGKILL) == -1) |
| | 514 | { |
| | 515 | fprintf(stderr, "kill() failed: %s (start)\n", strerror(errno)); |
| | 516 | } |
| | 517 | |
| | 518 | /* wait a while child to exit, we dont like zombie processes */ |
| | 519 | wait_child(control_ptr->pid); |