Exemplo n.º 1
0
static void
keep_alive_finalize(JSFreeOp *fop,
                    JSObject *obj)
{
    KeepAlive *priv;
    void *key;
    void *value;

    priv = (KeepAlive *) JS_GetPrivate(obj);

    gjs_debug_lifecycle(GJS_DEBUG_KEEP_ALIVE,
                        "keep_alive finalizing, obj %p priv %p", obj, priv);

    if (priv == NULL)
        return; /* we are the prototype, not a real instance */

    priv->inside_finalize = true;

    while (gjs_g_hash_table_steal_one(priv->children,
                                      &key, &value)) {
        Child *child = (Child *) value;
        if (child->notify)
            (* child->notify) (child->child, child->data);

        child_free(child);
    }

    g_hash_table_destroy(priv->children);
    g_slice_free(KeepAlive, priv);
}
Exemplo n.º 2
0
static void
keep_alive_finalize(JSContext *context,
                    JSObject  *obj)
{
    KeepAlive *priv;
    void *key;
    void *value;

    priv = priv_from_js(context, obj);

    gjs_debug_lifecycle(GJS_DEBUG_KEEP_ALIVE,
                        "keep_alive finalizing, obj %p priv %p", obj, priv);

    if (priv == NULL)
        return; /* we are the prototype, not a real instance, so constructor never called */

    priv->inside_finalize = TRUE;

    while (gjs_g_hash_table_steal_one(priv->children,
                                      &key, &value)) {
        Child *child = value;
        if (child->notify)
            (* child->notify) (child->child, child->data);

        child_free(child);
    }

    g_hash_table_destroy(priv->children);
    g_slice_free(KeepAlive, priv);
}
Exemplo n.º 3
0
gboolean
mainloop_child_kill(pid_t pid)
{
    GListPtr iter;
    mainloop_child_t *child = NULL;

    for (iter = child_list; iter != NULL; iter = iter->next) {
        child = iter->data;
        if (pid == child->pid) {
            break;
        }
    }

    if (child == NULL) {
        return FALSE;
    }

    if (child_kill_helper(child) != 0) {
        /* failed to terminate child process */
        return FALSE;
    }

    /* It is impossible to block SIGKILL, this allows us to
     * call waitpid without WNOHANG here */
    if (child_waitpid(child, 0) == FALSE) {
        /* not much we can do if this occurs */
        return FALSE;
    }

    child_list = g_list_remove(child_list, child);
    child_free(child);
    return TRUE;
}
Exemplo n.º 4
0
static void
mta_shutdown(void)
{
#ifdef VALGRIND
	child_free();
	free_peers();
	clean_setproctitle();
	event_base_free(NULL);
#endif

	log_info("mail transfer agent exiting");
	_exit(0);
}
Exemplo n.º 5
0
int
mainloop_child_kill(pid_t pid)
{
    GListPtr iter;
    mainloop_child_t *child = NULL;
    mainloop_child_t *match = NULL;
    /* It is impossible to block SIGKILL, this allows us to
     * call waitpid without WNOHANG flag.*/
    int waitflags = 0, rc = 0;

    for (iter = child_list; iter != NULL && match == NULL; iter = iter->next) {
        child = iter->data;
        if (pid == child->pid) {
            match = child;
        }
    }

    if (match == NULL) {
        return FALSE;
    }

    rc = child_kill_helper(match);
    if(rc == -ESRCH) {
        /* Its gone, but hasn't shown up in waitpid() yet
         *
         * Wait until we get SIGCHLD and let child_death_dispatch()
         * clean it up as normal (so we get the correct return
         * code/status)
         *
         * The blocking alternative would be to call:
         *    child_waitpid(match, 0);
         */
        crm_trace("Waiting for child %d to be reaped by child_death_dispatch()", match->pid);
        return TRUE;

    } else if(rc != 0) {
        /* If KILL for some other reason set the WNOHANG flag since we
         * can't be certain what happened.
         */
        waitflags = WNOHANG;
    }

    if (child_waitpid(match, waitflags) == FALSE) {
        /* not much we can do if this occurs */
        return FALSE;
    }

    child_list = g_list_remove(child_list, match);
    child_free(match);
    return TRUE;
}
Exemplo n.º 6
0
static void
control_shutdown(void)
{
#ifdef VALGRIND
	child_free();
	free_peers();
	clean_setproctitle();
	event_base_free(NULL);
#endif

	log_info("control process exiting");
	unlink(SMTPD_SOCKET);
	_exit(0);
}
Exemplo n.º 7
0
static void
child_death_dispatch(int signal)
{
    GListPtr iter = child_list;
    gboolean exited;

    while(iter) {
        GListPtr saved = NULL;
        mainloop_child_t *child = iter->data;
        exited = child_waitpid(child, WNOHANG);

        saved = iter;
        iter = iter->next;

        if (exited == FALSE) {
            continue;
        }
        crm_trace("Removing process entry %p for %d", child, child->pid);

        child_list = g_list_remove_link(child_list, saved);
        g_list_free(saved);
        child_free(child);
    }
}
Exemplo n.º 8
0
int main(int argc, char *argv[]) {
  int              backlog          = 10;
  muxer_t         *muxers[2]        = {NULL, NULL};
  status_writer_t *sw               = NULL;
  child_t         *child            = NULL;
  int              child_status     = -1;
  int              ring_buffer_size = 65535;
  int              fds[3]           = {-1, -1, -1};
  int              ii               = 0, exit_status = 0, nwritten = 0;
  pthread_t        sw_thread, muxer_threads[2];
  char             socket_paths[3][PATH_MAX + 1];
  char             *socket_names[3] = { "stdout.sock", "stderr.sock", "status.sock" };
  barrier_t        *barrier = NULL;

  if (argc < 3) {
    fprintf(stderr, "Usage: %s <socket directory> <cmd>\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  /* Setup listeners on domain sockets */
  for (ii = 0; ii < 3; ++ii) {
    memset(socket_paths[ii], 0, sizeof(socket_paths[ii]));
    nwritten = snprintf(socket_paths[ii], sizeof(socket_paths[ii]),
                        "%s/%s", argv[1], socket_names[ii]);
    if (nwritten >= sizeof(socket_paths[ii])) {
      fprintf(stderr, "Socket path too long\n");
      exit_status = 1;
      goto cleanup;
    }

    fds[ii] = create_unix_domain_listener(socket_paths[ii], backlog);

    DLOG("created listener, path=%s fd=%d", socket_paths[ii], fds[ii]);

    if (-1 == fds[ii]) {
      perrorf("Failed creating socket at %s:", socket_paths[ii]);
      exit_status = 1;
      goto cleanup;
    }

    set_cloexec(fds[ii]);
  }

  child = child_create(argv + 2, argc - 2);

  printf("child_pid=%d\n", child->pid);
  fflush(stdout);

  /* Muxers for stdout/stderr */
  muxers[0] = muxer_alloc(fds[0], child->stdout[0], ring_buffer_size);
  muxers[1] = muxer_alloc(fds[1], child->stderr[0], ring_buffer_size);
  for (ii = 0; ii < 2; ++ii) {
    if (pthread_create(&muxer_threads[ii], NULL, run_muxer, muxers[ii])) {
      perrorf("Failed creating muxer thread:");
      exit_status = 1;
      goto cleanup;
    }

    DLOG("created muxer thread for socket=%s", socket_paths[ii]);
  }

  /* Status writer */
  barrier = barrier_alloc();
  sw = status_writer_alloc(fds[2], barrier);
  if (pthread_create(&sw_thread, NULL, run_status_writer, sw)) {
    perrorf("Failed creating muxer thread:");
    exit_status = 1;
    goto cleanup;
  }

  /* Wait for clients on stdout, stderr, and status */
  for (ii = 0; ii < 2; ++ii) {
    muxer_wait_for_client(muxers[ii]);
  }
  barrier_wait(barrier);

  child_continue(child);

  printf("child active\n");
  fflush(stdout);

  if (-1 == waitpid(child->pid, &child_status, 0)) {
    perrorf("Waitpid for child failed: ");
    exit_status = 1;
    goto cleanup;
  }

  DLOG("child exited, status = %d", WEXITSTATUS(child_status));

  /* Wait for status writer */
  status_writer_finish(sw, child_status);
  pthread_join(sw_thread, NULL);

  /* Wait for muxers */
  for (ii = 0; ii < 2; ++ii) {
    muxer_stop(muxers[ii]);
    pthread_join(muxer_threads[ii], NULL);
  }

  DLOG("all done, cleaning up and exiting");

cleanup:
  if (NULL != child) {
    child_free(child);
  }

  if (NULL != barrier) {
    barrier_free(barrier);
  }

  if (NULL != sw) {
    status_writer_free(sw);
  }

  for (ii = 0; ii < 2; ++ii) {
    if (NULL != muxers[ii]) {
      muxer_free(muxers[ii]);
    }
  }

  /* Close accept sockets and clean up paths */
  for (ii = 0; ii < 3; ++ii) {
    if (-1 != fds[ii]) {
      close(fds[ii]);
      unlink(socket_paths[ii]);
    }
  }

  return exit_status;
}