示例#1
0
文件: test.c 项目: zgbkny/ctoolx
/*
 * General server example: accept a client connection and do something.
 * This program just outputs a short HTML page, but can be easily adapted
 * to do other things.
 *
 * This server creates a constant number of processes ("virtual processors"
 * or VPs) and replaces them when they die. Each virtual processor manages
 * its own independent set of state threads (STs), the number of which varies
 * with load against the server. Each state thread listens to exactly one
 * listening socket. The initial process becomes the watchdog, waiting for
 * children (VPs) to die or for a signal requesting termination or restart.
 * Upon receiving a restart signal (SIGHUP), all VPs close and then reopen
 * log files and reload configuration. All currently active connections remain
 * active. It is assumed that new configuration affects only request
 * processing and not the general server parameters such as number of VPs,
 * thread limits, bind addresses, etc. Those are specified as command line
 * arguments, so the server has to be stopped and then started again in order
 * to change them.
 *
 * Each state thread loops processing connections from a single listening
 * socket. Only one ST runs on a VP at a time, and VPs do not share memory,
 * so no mutual exclusion locking is necessary on any data, and the entire
 * server is free to use all the static variables and non-reentrant library
 * functions it wants, greatly simplifying programming and debugging and
 * increasing performance (for example, it is safe to ++ and -- all global
 * counters or call inet_ntoa(3) without any mutexes). The current thread on
 * each VP maintains equilibrium on that VP, starting a new thread or
 * terminating itself if the number of spare threads exceeds the lower or
 * upper limit.
 *
 * All I/O operations on sockets must use the State Thread library's I/O
 * functions because only those functions prevent blocking of the entire VP
 * process and perform state thread scheduling.
 */
int main(int argc, char *argv[])
{
  /* Parse command-line options */
  parse_arguments(argc, argv);

  /* Allocate array of server pids */
  if ((vp_pids = calloc(vp_count, sizeof(pid_t))) == NULL)
    err_sys_quit(errfd, "ERROR: calloc failed");

  /* Start the daemon */
  if (!interactive_mode)
    start_daemon();

  /* Initialize the ST library */
  if (st_init() < 0)
    err_sys_quit(errfd, "ERROR: initialization failed: st_init");

  /* Set thread throttling parameters */
  set_thread_throttling();

  /* Create listening sockets */
  create_listeners();

  /* Change the user */
  if (username)
    change_user();

  /* Open log files */
  open_log_files();

  /* Start server processes (VPs) */
  start_processes();

  /* Turn time caching on */
  st_timecache_set(1);

  /* Install signal handlers */
  install_sighandlers();

  /* Load configuration from config files */
  load_configs();

  /* Start all threads */
  start_threads();

  /* Become a signal processing thread */
  process_signals(NULL);

  /* NOTREACHED */
  return 1;
}
示例#2
0
/*********************************************************************
 * open connections and send requested amt of data; estimate b/w
 */
void
simple_server(int num_ports, int base_rx_port)
{
    int datafd, maxlfd;
    unsigned long diffus;
    struct timeval last, diff, now ={ 0L, 0L };
    int opened=0, closed=0, cnt=0; 
    fd_set fds_listeners, fds_active, fds_finished;

    int rc;

    FD_ZERO(&fds_listeners);
    FD_ZERO(&fds_active);
    FD_ZERO(&fds_finished);

    /* listeners on num_ports */
    if((maxlfd = create_listeners(&fds_listeners, num_ports, base_rx_port)) < 0)
    {
	exit(-1);
    }

    datafd = maxlfd+1;

    while(1)
    {
	/* grab any new incoming connections */
	rc = accept_incoming(maxlfd, &fds_listeners, &fds_active);
	if(rc > 0)
	{
	    opened += rc;
	}
	/*  select on the data FD's */
	rc = send_data(&fds_active, &fds_finished);
	if(rc > 0)
	{
	    closed += rc;
	}
	cnt++; 
	
	gettimeofday(&now, (struct timezone *)0);
	
	tvsub(&diff, &now, &last);
	diffus = diff.tv_sec*1e6 + diff.tv_usec;
	
	if(diffus > SAMPLE_PERIOD)
	{
	    int i, totb=0, prog=0;
	    double mbs, tmbs=0.0;

	    fprintf(stderr, "\nBandwidth:\n");

	    for(i=datafd; i <= maxfd; i++)
	    {
		if(state[i].tx_sent_cpt) 
		{
		    prog++;
		}
		totb += state[i].tx_sent_cpt;
		mbs   = (double)(8.0*state[i].tx_sent_cpt) / (double)diffus;
		tmbs += mbs;
	      
		if(state[i].open) 
		{
		    fprintf(stderr,"%c%.4f ",'+', mbs);
		}
		else
		{
		    if(verbose)
		    {
			fprintf(stderr,"%c%.4f ",'-', mbs);
		    }
		}

		state[i].tx_sent_cpt = 0;
	    }

	    fprintf(stderr, 
		    "\n\t %d streams active, %d made progress: "
		    "tot = %d, tot Mb/s = %.2f\n"
		    "\t opened %d, closed %d descriptors (loop count %d)\n\n",
		    FD_POP(maxfd, &fds_active), prog, 
		    totb, tmbs/scalar, 
		    opened, closed, cnt);
	    
	    opened = closed = cnt = 0;
	    last = now; 
	}
    } /* end of while 1 */
}