Exemplo n.º 1
0
static void cleanup_env(void)
{
	if (g_role == arbiter) {
		cleanup_arbiter();
	} else {
		cleanup_child();
	}
}
Exemplo n.º 2
0
static void
rsn_dec_dispose (GObject * object)
{
  RsnDec *self = (RsnDec *) object;
  cleanup_child (self);

  G_OBJECT_CLASS (rsn_dec_parent_class)->dispose (object);
}
Exemplo n.º 3
0
static GstStateChangeReturn
rsn_dec_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  RsnDec *self = RSN_DEC (element);
  RsnDecClass *klass = RSN_DEC_GET_CLASS (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:{
      GstElement *new_child;
      const GList *decoder_factories;

      new_child = gst_element_factory_make ("autoconvert", NULL);
      decoder_factories = klass->get_decoder_factories (klass);
      g_object_set (G_OBJECT (new_child), "factories", decoder_factories, NULL);
      if (new_child == NULL || !rsn_dec_set_child (self, new_child))
        ret = GST_STATE_CHANGE_FAILURE;
      break;
    }
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      break;
    default:
      break;
  }

  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;
  ret =
      GST_ELEMENT_CLASS (rsn_dec_parent_class)->change_state (element,
      transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      cleanup_child (self);
      break;
    default:
      break;
  }

  return ret;
}
Exemplo n.º 4
0
int exec_wait()
{
    int         i, j;
    int         ret;
    int         fd_max;
    int         pid;
    int         status;
    int         finished;
    fd_set      fds;

    /* Handle naive make1() which does not know if commands are running. */
    if ( !cmdsrunning )
        return 0;

    /* Process children that signaled. */
    finished = 0;
    while ( !finished && cmdsrunning )
    {
        /* Compute max read file descriptor for use in select(). */
        populate_file_descriptors( &fd_max, &fds );

        if ( 0 < globs.timeout )
        {
            /* Force select() to timeout so we can terminate expired processes.
             */
            tv.tv_sec = select_timeout;
            tv.tv_nsec = 0;

            /* select() will wait until: i/o on a descriptor, a signal, or we
             * time out.
             */
            ret = pselect( fd_max + 1, &fds, 0, 0, &tv, &empty_sigmask );
        }
        else
        {
            /* pselect() will wait until i/o on a descriptor or a signal. */
            ret = pselect( fd_max + 1, &fds, 0, 0, 0, &empty_sigmask );
        }

        if (-1 == ret && errno != EINTR) {
            perror("pselect()");
            exit(-1);
        }

        if (0 < child_events) {
            /* child terminated via SIGCHLD */
            for (i=0; i<MAXJOBS; ++i) {
                if (0 < terminated_children[i].pid) {
                    pid_t pid = terminated_children[i].pid;
                    /* get index of terminated pid */
                    for (j=0; j<globs.jobs; ++j) {
                        if (pid == cmdtab[j].pid) {
                            /* cleanup loose ends for terminated process */
                            close_streams(j, OUT);
                            if ( globs.pipe_action != 0 ) close_streams(j, ERR);
                            cleanup_child(j, terminated_children[i].status);
                            --cmdsrunning;
                            finished = 1;
                            break;
                        }
                    }
                    /* clear entry from list */
                    terminated_children[i].status = 0;
                    terminated_children[i].pid = 0;
                    --child_events;
                }
            }
        }

        if ( 0 < ret )
        {
            for ( i = 0; i < globs.jobs; ++i )
            {
                int out = 0;
                int err = 0;
                if ( FD_ISSET( cmdtab[ i ].fd[ OUT ], &fds ) )
                    out = read_descriptor( i, OUT );

                if ( ( globs.pipe_action != 0 ) &&
                    ( FD_ISSET( cmdtab[ i ].fd[ ERR ], &fds ) ) )
                    err = read_descriptor( i, ERR );

                /* If feof on either descriptor, then we are done. */
                if ( out || err )
                {
                    /* Close the stream and pipe descriptors. */
                    close_streams( i, OUT );
                    if ( globs.pipe_action != 0 )
                        close_streams( i, ERR );

                    /* Reap the child and release resources. */
                    pid = waitpid( cmdtab[ i ].pid, &status, 0 );

                    if ( pid == cmdtab[ i ].pid )
                    {
                        /* move into function so signal handler can also use */
                        finished = 1;
                        cleanup_child(i, status);
                        --cmdsrunning;
                    }
                    else
                    {
                        printf( "unknown pid %d with errno = %d\n", pid, errno );
                        exit( EXITBAD );
                    }
                }
            }
        }
    }
    return 1;
}
Exemplo n.º 5
0
/*
 * child_fn() - Inside container
 *
 * XXX (garrcoop): add more calls to cleanup_child()?
 */
int child_fn(void *arg)
{
	pid_t pid, ppid;
	struct sigaction sa;
	struct sigevent notif;
	char buf[5];

	/* Set process id and parent pid */
	pid = getpid();
	ppid = getppid();

	if (pid != CHILD_PID || ppid != PARENT_PID) {
		printf("pidns was not created\n");
		return 1;
	}

	/* Close the appropriate end of each pipe */
	close(child_to_father[0]);
	close(father_to_child[1]);

	while (read(father_to_child[0], buf, 1) != 1)
		sleep(1);

	mqd = syscall(__NR_mq_open, mqname, O_RDONLY);
	if (mqd == -1) {
		perror("mq_open failed");
		return 1;
	} else
		printf("mq_open succeeded\n");

	/* Register for notification on message arrival */
	notif.sigev_notify = SIGEV_SIGNAL;
	notif.sigev_signo = SIGUSR1;
	notif.sigev_value.sival_int = mqd;
	if (syscall(__NR_mq_notify, mqd, &notif) == -1) {
		perror("mq_notify failed");
		return 1;
	} else
		printf("successfully registered for notification\n");

	/* Define handler for SIGUSR1 */
	sa.sa_flags = SA_SIGINFO;
	sigemptyset(&sa.sa_mask);
	sa.sa_sigaction = child_signal_handler;
	if (sigaction(SIGUSR1, &sa, NULL) == -1) {
		perror("sigaction failed");
		return 1;
	} else
		printf("successfully registered handler for SIGUSR1\n");

	/* Ask parent to send a message to the mqueue */
	if (write(child_to_father[1], "c:ok", 5) != 5) {
		perror("write failed");
		return 1;
	}

	sleep(3);

	/* Has parent sent a message? */
	read(father_to_child[0], buf, 5);
	if (strcmp(buf, "f:ok") != 0) {
		printf("parent did not send the message!\n");
		return 1;
	}
	printf("parent is done - cleaning up\n");

	cleanup_child();

	exit(0);
}
Exemplo n.º 6
0
/*
 * Wait for up to <threshold> seconds for a exec-ed process to finish.
 * If the process completes the cleanup function is called to cleanup
 * and the status is returned.
 *
 * If the procees did not complete the cleanup function is launched in a new
 * thread to wait for the process to complete asynchronously and control
 * is retuned to the caller with a -2 return.
 *
 * The cleanup function must continue to wait on the pid and cleanup
 * after the process exits by closing file descriptors, freeing any
 * associated memory and calling end_this_activity for the job.
 *
 * start_activity must be called prior to calling this function.
 *
 * Returns:
 *	 0  process exited successfully, cleanup_child has been called
 *	-1  process exited with an error, cleanup_child has been called
 *	-2  process did not yet complete. The cleanup function has been
 *	    called to wait for it.
 */
int
bounded_activity_wait(
int *status,
int threshold,
char *jobid,
pid_t pid,
void *cl_args,
void * (*cleanup_child)(void *))
{

	/* variables to control the transition to asynchronous */
	int		total_wait = 0;
	int		ret_val = 0;
	pthread_t	tid;
	timespec_t	waitspec = {1, 0};

	Trace(TR_DEBUG, "about to enter wait for process %ld", pid);
	if (ISNULL(status, jobid, cl_args, cleanup_child)) {
		Trace(TR_ERR, "bounded wait err: %d %s", samerrno, samerrmsg);
		return (-1);
	}
	/*
	 * wait for the process without hanging and leave it as you
	 * found it so the cleanup function can handle its completion
	 * error as it sees fit.
	 */
	for (;;) {
		ret_val = waitpid(pid, status, WNOHANG | WNOWAIT);
		if (ret_val == -1 && errno != EINTR) {
			/* waitpid hit an error */
			break;
		} else if (ret_val == pid) {
			/* the process is done */
			break;
		}

		nanosleep(&waitspec, NULL);
		total_wait += 1;

		if (total_wait >= threshold) {
			Trace(TR_MISC, "going asynch for %s(%ld)",
			    Str(jobid), pid);

			/* go asynchronous */
			pthread_create(&tid, &samr_pth_attr, cleanup_child,
			    cl_args);

			set_pid_or_tid(jobid, 0, tid);
			return (-2);
		}
	}

	/* the process either exited (error or success) or waitpid failed */

	/* call the cleanup function in this thread */
	cleanup_child(cl_args);

	if (ret_val < 0 || !WIFEXITED(*status) || WEXITSTATUS(*status)) {
		/*
		 * wait failed OR process abnormally terminated OR
		 * process exited with non zero exit code
		 */
		return (-1);
	} else {
		return (0);
	}
}