Lines Matching refs:lsp
34 struct lws_spawn_piped *lsp = lws_container_of(sul,
39 lws_spawn_piped_kill_child_process(lsp);
45 struct lws_spawn_piped *lsp = lws_container_of(sul,
49 __func__, lsp->reap_retry_budget);
50 if (!lws_spawn_reap(lsp) && !lsp->pipes_alive) {
51 if (--lsp->reap_retry_budget) {
52 lws_sul_schedule(lsp->info.vh->context, lsp->info.tsi,
53 &lsp->sul_reap, lws_spawn_sul_reap,
56 lwsl_err("%s: Unable to reap lsp %p, killing\n",
57 __func__, lsp);
58 lsp->reap_retry_budget = 20;
59 lws_spawn_piped_kill_child_process(lsp);
113 struct lws_spawn_piped *lsp = *_lsp;
117 if (!lsp)
121 if (lsp->pipe_fds[n][!!(n == 0)]) {
122 CloseHandle(lsp->pipe_fds[n][n == 0]);
123 lsp->pipe_fds[n][n == 0] = NULL;
127 if (lsp->stdwsi[n]) {
129 wsi = lsp->stdwsi[n];
130 lsp->stdwsi[n]->desc.filefd = NULL;
131 lsp->stdwsi[n] = NULL;
137 lws_dll2_remove(&lsp->dll);
139 lws_sul_cancel(&lsp->sul);
140 lws_sul_cancel(&lsp->sul_reap);
141 lws_sul_cancel(&lsp->sul_poll);
143 lwsl_warn("%s: deleting lsp\n", __func__);
149 lws_spawn_reap(struct lws_spawn_piped *lsp)
152 void *opaque = lsp->info.opaque;
153 lsp_cb_t cb = lsp->info.reap_cb;
158 if (!lsp->child_pid)
161 if (!GetExitCodeProcess(lsp->child_pid, &ex)) {
174 if (!lsp->reaped) {
175 lsp->reaped = lws_now_usecs();
182 lws_sul_schedule(lsp->info.vh->context, lsp->info.tsi,
183 &lsp->sul, lws_spawn_timeout,
194 if (!lsp->ungraceful && lsp->pipes_alive) {
201 lws_sul_cancel(&lsp->sul);
210 lsp->child_pid = NULL;
212 /* destroy the lsp itself first (it's freed and plsp set NULL */
214 if (lsp->info.plsp)
215 lws_spawn_piped_destroy(lsp->info.plsp);
229 lws_spawn_piped_kill_child_process(struct lws_spawn_piped *lsp)
231 if (!lsp->child_pid)
234 lsp->ungraceful = 1; /* don't wait for flushing, just kill it */
236 if (lws_spawn_reap(lsp))
237 /* that may have invalidated lsp */
241 TerminateProcess(lsp->child_pid, 252);
242 lws_spawn_reap(lsp);
244 /* that may have invalidated lsp */
252 struct lws_spawn_piped *lsp = lws_container_of(sul,
259 * Do it first, we know lsp exists and if it's destroyed inbetweentimes,
263 lws_sul_schedule(lsp->context, 0, &lsp->sul_poll,
266 wsi = lsp->stdwsi[LWS_STDOUT];
267 wsi1 = lsp->stdwsi[LWS_STDERR];
268 if (wsi && lsp->pipe_fds[LWS_STDOUT][0] != NULL) {
269 if (!PeekNamedPipe(lsp->pipe_fds[LWS_STDOUT][0], &c, 1, &br,
273 CloseHandle(lsp->stdwsi[LWS_STDOUT]->desc.filefd);
274 lsp->pipe_fds[LWS_STDOUT][0] = NULL;
275 lsp->stdwsi[LWS_STDOUT]->desc.filefd = NULL;
276 lsp->stdwsi[LWS_STDOUT] = NULL;
279 if (lsp->stdwsi[LWS_STDIN]) {
282 CloseHandle(lsp->stdwsi[LWS_STDIN]->desc.filefd);
283 wsi = lsp->stdwsi[LWS_STDIN];
284 lsp->stdwsi[LWS_STDIN]->desc.filefd = NULL;
285 lsp->stdwsi[LWS_STDIN] = NULL;
286 lsp->pipe_fds[LWS_STDIN][1] = NULL;
291 * lsp may be destroyed by here... if we wanted to
304 * lsp may have been destroyed above
307 if (wsi1 && lsp->pipe_fds[LWS_STDERR][0]) {
308 if (!PeekNamedPipe(lsp->pipe_fds[LWS_STDERR][0], &c, 1, &br,
314 * Assume is stderr still extant on entry, lsp can't
317 lsp->stdwsi[LWS_STDERR]->desc.filefd = NULL;
318 lsp->stdwsi[LWS_STDERR] = NULL;
319 lsp->pipe_fds[LWS_STDERR][0] = NULL;
322 * lsp may have been destroyed above
344 struct lws_spawn_piped *lsp;
360 lsp = lws_zalloc(sizeof(*lsp), __func__);
361 if (!lsp) {
367 lsp->info = *i;
368 lsp->context = context;
369 lsp->reap_retry_budget = 20;
376 lsp->pipe_fds[n][0] = NULL;
377 lsp->pipe_fds[n][1] = NULL;
390 if (!CreatePipe(&lsp->pipe_fds[n][0], &lsp->pipe_fds[n][1],
396 SetNamedPipeHandleState(lsp->pipe_fds[1][0], &waitmode, NULL, NULL);
397 SetNamedPipeHandleState(lsp->pipe_fds[2][0], &waitmode, NULL, NULL);
401 if (!SetHandleInformation(&lsp->pipe_fds[n][!n],
411 lsp->stdwsi[n] = lws_create_basic_wsi(i->vh->context, i->tsi,
413 if (!lsp->stdwsi[n]) {
414 lwsl_err("%s: unable to create lsp stdwsi\n", __func__);
419 &lsp->stdwsi[n]->lc, "nspawn-stdwsi-%d", n);
421 lsp->stdwsi[n]->lsp_channel = n;
422 lws_vhost_bind_wsi(i->vh, lsp->stdwsi[n]);
423 lsp->stdwsi[n]->a.protocol = pcol;
424 lsp->stdwsi[n]->a.opaque_user_data = i->opaque;
426 lsp->stdwsi[n]->desc.filefd = lsp->pipe_fds[n][!n];
427 lsp->stdwsi[n]->file_desc = 1;
429 lwsl_debug("%s: lsp stdwsi %p: pipe idx %d -> fd %d / %d\n",
430 __func__, lsp->stdwsi[n], n,
431 lsp->pipe_fds[n][!!(n == 0)],
432 lsp->pipe_fds[n][!(n == 0)]);
438 lsp->stdwsi[n]->desc.filefd = lsp->pipe_fds[n][!!(n == 0)];
439 if (fcntl(lsp->pipe_fds[n][!!(n == 0)], F_SETFL, O_NONBLOCK) < 0) {
448 lsp->stdwsi[n]->parent = i->opt_parent;
449 lsp->stdwsi[n]->sibling_list = i->opt_parent->child_list;
450 i->opt_parent->child_list = lsp->stdwsi[n];
454 lsp->stdwsi[LWS_STDIN]->desc.sockfd,
455 lsp->stdwsi[LWS_STDOUT]->desc.sockfd,
456 lsp->stdwsi[LWS_STDERR]->desc.sockfd);
465 lws_sul_schedule(context, 0, &lsp->sul_poll, windows_pipe_poll_hack,
491 si.hStdInput = lsp->pipe_fds[LWS_STDIN][0];
492 si.hStdOutput = lsp->pipe_fds[LWS_STDOUT][1];
493 si.hStdError = lsp->pipe_fds[LWS_STDERR][1];
503 lsp->child_pid = pi.hProcess;
505 lwsl_notice("%s: lsp %p spawned PID %d\n", __func__, lsp, lsp->child_pid);
507 lws_sul_schedule(context, i->tsi, &lsp->sul, lws_spawn_timeout,
514 CloseHandle(lsp->pipe_fds[n][n != 0]);
516 lsp->pipes_alive = 3;
517 lsp->created = lws_now_usecs();
520 lws_dll2_add_head(&lsp->dll, i->owner);
523 lws_sul_schedule(context, i->tsi, &lsp->sul,
526 return lsp;
530 lws_sul_cancel(&lsp->sul_poll);
533 __remove_wsi_socket_from_fds(lsp->stdwsi[n]);
536 if (lsp->stdwsi[n])
537 __lws_free_wsi(lsp->stdwsi[n]);
541 if (lsp->pipe_fds[n][0] >= 0)
542 CloseHandle(lsp->pipe_fds[n][0]);
543 if (lsp->pipe_fds[n][1] >= 0)
544 CloseHandle(lsp->pipe_fds[n][1]);
547 lws_free(lsp);
555 lws_spawn_stdwsi_closed(struct lws_spawn_piped *lsp, struct lws *wsi)
559 assert(lsp);
560 lsp->pipes_alive--;
561 lwsl_debug("%s: pipes alive %d\n", __func__, lsp->pipes_alive);
562 if (!lsp->pipes_alive)
563 lws_sul_schedule(lsp->info.vh->context, lsp->info.tsi,
564 &lsp->sul_reap, lws_spawn_sul_reap, 1);
567 if (lsp->stdwsi[n] == wsi)
568 lsp->stdwsi[n] = NULL;