Пример #1
0
AP_DECLARE(void) ap_wait_or_timeout(apr_exit_why_e *status, int *exitcode,
                                    apr_proc_t *ret, apr_pool_t *p,
                                    server_rec *s)
{
    apr_status_t rv;

    ++wait_or_timeout_counter;
    if (wait_or_timeout_counter == INTERVAL_OF_WRITABLE_PROBES) {
        wait_or_timeout_counter = 0;
        ap_run_monitor(p, s);
    }

    rv = apr_proc_wait_all_procs(ret, exitcode, status, APR_NOWAIT, p);
    ap_update_global_status();

    if (APR_STATUS_IS_EINTR(rv)) {
        ret->pid = -1;
        return;
    }

    if (APR_STATUS_IS_CHILD_DONE(rv)) {
        return;
    }

    apr_sleep(apr_time_from_sec(1));
    ret->pid = -1;
}
Пример #2
0
/*
 *
 * Function: checkExitedSystem
 * Description:  检查退出的子系统
 * Input: 
 * OutPut:
 *      
 * Return:
 * Other:
 *
 */
void CommandServer::checkExitedSystem( void )
{
   int iExitCode, iIdx;
   apr_exit_why_e tWhy;
   apr_status_t tStatus;
   apr_proc_t   stProcess;

   do
   {
      tStatus = apr_proc_wait_all_procs( &stProcess, &iExitCode, &tWhy,
                                         APR_NOWAIT, m_pstLocal );
      if( stProcess.pid > 0 && !APR_STATUS_IS_EINTR(tStatus) )
      {
         /*设置该子系统为可用*/
         for( iIdx = 0; iIdx < m_pstConfig->m_iMaxSys; iIdx++ )
         {
            if( m_pstSystem[iIdx].m_tManagerPid == stProcess.pid )
            {
               m_pstSystem[iIdx].m_tManagerPid = 0;
               m_pstSystem[iIdx].m_bActive = false;
               break;
            }
         }
         if( iIdx == m_pstConfig->m_iMaxSys )
         {
            LOG4C(( LOG_WARN, "请尽快检查系统,有个进程%d不知道怎么来的\n",
                    stProcess.pid ));
         }
      }
      else
      {
         return;
      }
   } while( true );
}
Пример #3
0
void ap_wait_or_timeout(apr_exit_why_e *status, int *exitcode, apr_proc_t *ret,
                        apr_pool_t *p)
{
    apr_status_t rv;

    ++wait_or_timeout_counter;
    if (wait_or_timeout_counter == INTERVAL_OF_WRITABLE_PROBES) {
        wait_or_timeout_counter = 0;
        ap_run_monitor(p);
    }

    rv = apr_proc_wait_all_procs(ret, exitcode, status, APR_NOWAIT, p);
    if (APR_STATUS_IS_EINTR(rv)) {
        ret->pid = -1;
        return;
    }

    if (APR_STATUS_IS_CHILD_DONE(rv)) {
        return;
    }

#ifdef NEED_WAITPID
    if ((ret = reap_children(exitcode, status)) > 0) {
        return;
    }
#endif

    apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL);
    ret->pid = -1;
    return;
}
Пример #4
0
/* This is needed to reap processes spawned by exec_async() */
static void xm_exec_reap(nx_module_t *module)
{
    nx_xm_exec_conf_t *imconf;
    nx_event_t *event;
    apr_exit_why_e exitwhy;
    int exitval;
    apr_status_t rv;
    apr_proc_t proc;

    ASSERT(module->config != NULL);

    imconf = (nx_xm_exec_conf_t *) module->config;

    while ( APR_STATUS_IS_CHILD_DONE(rv = apr_proc_wait_all_procs(&proc, &exitval,
								  &exitwhy, APR_NOWAIT, NULL)) )
    {
	log_debug("process %d reaped by xm_exec_reap", proc.pid);

	if ( proc.pid > 0 )
	{
	    if ( exitwhy == APR_PROC_EXIT )
	    { //normal termination
		if ( exitval != 0 )
		{
		    log_error("subprocess '%d' returned a non-zero exit value of %d",
			      proc.pid, exitval);
		}
	    }
	    else
	    {
		log_error("subprocess '%d' was terminated by a signal", proc.pid); 
	    }
	}
	else
	{ // on windows we get PID = -1 and it would result in an endless loop during exit
	    break;
	}
    }

    event = nx_event_new();
    event->module = module;
    event->type = NX_EVENT_MODULE_SPECIFIC;
    event->delayed = TRUE;
    event->time = apr_time_now() + APR_USEC_PER_SEC;
    event->priority = module->priority;
    nx_event_add(event);
    imconf->event = event;
}
Пример #5
0
/* Wait for the next client connection to come in from SOCK.  Allocate
 * the connection in a root pool from CONNECTION_POOLS and assign PARAMS.
 * Return the connection object in *CONNECTION.
 *
 * Use HANDLING_MODE for proper internal cleanup.
 */
static svn_error_t *
accept_connection(connection_t **connection,
                  apr_socket_t *sock,
                  serve_params_t *params,
                  enum connection_handling_mode handling_mode,
                  apr_pool_t *pool)
{
  apr_status_t status;

  /* Non-standard pool handling.  The main thread never blocks to join
   *         the connection threads so it cannot clean up after each one.  So
   *         separate pools that can be cleared at thread exit are used. */

  apr_pool_t *connection_pool = svn_pool_create(pool);
  *connection = apr_pcalloc(connection_pool, sizeof(**connection));
  (*connection)->pool = connection_pool;
  (*connection)->params = params;
  (*connection)->ref_count = 1;

  do
    {
      #ifdef WIN32
      if (winservice_is_stopping())
        exit(0);
      #endif

      status = apr_socket_accept(&(*connection)->usock, sock,
                                 connection_pool);
      if (handling_mode == connection_mode_fork)
        {
          apr_proc_t proc;

          /* Collect any zombie child processes. */
          while (apr_proc_wait_all_procs(&proc, NULL, NULL, APR_NOWAIT,
            connection_pool) == APR_CHILD_DONE)
            ;
        }
    }
  while (APR_STATUS_IS_EINTR(status)
    || APR_STATUS_IS_ECONNABORTED(status)
    || APR_STATUS_IS_ECONNRESET(status));

  return status
       ? svn_error_wrap_apr(status, _("Can't accept client connection"))
       : SVN_NO_ERROR;
}
/*
 * Handle post-rotate processing.
 */
static void post_rotate(apr_pool_t *pool, struct logfile *newlog,
                        rotate_config_t *config, rotate_status_t *status)
{
    apr_status_t rv;
    char error[120];
    apr_procattr_t *pattr;
    const char *argv[4];
    apr_proc_t proc;

    /* Handle link file, if configured. */
    if (config->linkfile) {
        apr_file_remove(config->linkfile, newlog->pool);
        if (config->verbose) {
            fprintf(stderr,"Linking %s to %s\n", newlog->name, config->linkfile);
        }
        rv = apr_file_link(newlog->name, config->linkfile);
        if (rv != APR_SUCCESS) {
            apr_strerror(rv, error, sizeof error);
            fprintf(stderr, "Error linking file %s to %s (%s)\n",
                    newlog->name, config->linkfile, error);
            exit(2);
        }
    }

    if (!config->postrotate_prog) {
        /* Nothing more to do. */
        return;
    }

    /* Collect any zombies from a previous run, but don't wait. */
    while (apr_proc_wait_all_procs(&proc, NULL, NULL, APR_NOWAIT, pool) == APR_CHILD_DONE)
        /* noop */;

    if ((rv = apr_procattr_create(&pattr, pool)) != APR_SUCCESS) {
        fprintf(stderr,
                "post_rotate: apr_procattr_create failed for '%s': %s\n",
                config->postrotate_prog,
                apr_strerror(rv, error, sizeof(error)));
        return;
    }

    rv = apr_procattr_error_check_set(pattr, 1);
    if (rv == APR_SUCCESS)
        rv = apr_procattr_cmdtype_set(pattr, APR_PROGRAM_ENV);

    if (rv != APR_SUCCESS) {
        fprintf(stderr,
                "post_rotate: could not set up process attributes for '%s': %s\n",
                config->postrotate_prog,
                apr_strerror(rv, error, sizeof(error)));
        return;
    }

    argv[0] = config->postrotate_prog;
    argv[1] = newlog->name;
    if (status->current.fd) {
        argv[2] = status->current.name;
        argv[3] = NULL;
    }
    else {
        argv[2] = NULL;
    }

    if (config->verbose)
        fprintf(stderr, "Calling post-rotate program: %s\n", argv[0]);

    rv = apr_proc_create(&proc, argv[0], argv, NULL, pattr, pool);
    if (rv != APR_SUCCESS) {
        fprintf(stderr, "Could not spawn post-rotate process '%s': %s\n",
                config->postrotate_prog,
                apr_strerror(rv, error, sizeof(error)));
        return;
    }
}