Exemple #1
0
void input_start_stdin(int fd)
{
  if (read_stream) {
    return;
  }

  read_buffer = rbuffer_new(READ_BUFFER_SIZE);
  read_stream = rstream_new(read_cb, read_buffer, NULL);
  rstream_set_file(read_stream, fd);
  rstream_start(read_stream);
}
Exemple #2
0
// new a net pool
struct net_pool* net_new()
{
    struct net_pool* np = (struct net_pool*)malloc(sizeof(struct net_pool));

    // get the eventfd
    np->eventfd = poll_create();
    if(poll_invalid(np->eventfd))
    {
        log_error("epoll create failure\n");
        return NULL;
    }

    np->eventn = 0;
    np->eventindex = 0;
    np->allocid = 0;
    np->count = 0;
    np->cap = DEFAULT_SOCKET;

    // beforehand alloc an array as a container
    np->ns = (struct net_socket**)malloc(np->cap * sizeof(struct net_socket*));

    // initialize the elements of array: alloc memory
    int i = 0;
    for(; i < np->cap; ++i)
    {
        np->ns[i] = (struct net_socket*)malloc(sizeof(struct net_socket));
        memset(np->ns[i], 0, sizeof(struct net_socket));
        np->ns[i]->rdsz = MIN_READ_BUFFER;
        np->ns[i]->wbuff = wbuffer_new();
        np->ns[i]->rbuff = rbuffer_new();
    }

    np->ud = NULL;


    // set signal to np
    net_set_sighandler(np);

    // np->prothandler = (map<int, PROTHANDLER>*)malloc(sizeof(map<int, PROTHANDLER>)) ;
    // map is a type of class, use new, call structure function

    np->prothandler = new map<int, PROTHANDLER>;
    np->onlineconnidtocharid = new map<int, int>;
    np->onlinecharidtoconnid = new map<int, int>;

    np->serverid = -1;

    return np;
}
Exemple #3
0
// expand the capacity
static void net_expand(struct net_pool* np)
{
    log_debug("net_expand ...\n");
    int newcap = np->cap * 2;

    // new array for saving net socket's information
    struct net_socket** ns = (struct net_socket**)malloc(newcap * sizeof(struct net_socket*));
    memset(ns, 0, newcap * sizeof(struct net_socket*));

    int i = 0;
    // transplant the old data to new container
    for(; i < np->cap; ++i)
    {
        // in fact, np->ns[i]->id == i
        // use %, incase of spilling
        int nid = np->ns[i]->id % newcap;
        if(ns[nid] != NULL)
        {
            log_error("new net_socket error : %d", i);
            continue;
        }
        ns[nid] = np->ns[i];
    }

    // malloc new container's data
    for(i = 0; i < newcap; ++i)
    {
        if(!ns[i])
        {
            ns[i] = (struct net_socket*)malloc(sizeof(struct net_socket));
            memset(ns[i], 0, sizeof(struct net_socket));
            ns[i]->rdsz = MIN_READ_BUFFER;
            ns[i]->rbuff = rbuffer_new();
            ns[i]->wbuff = wbuffer_new();
        }
    }

    // free the old array
    free(np->ns);
    // set the new array
    np->ns = ns;
    // increse the cap
    np->cap = newcap;
}
Exemple #4
0
/// Tries to start a new job.
///
/// @param[out] status The job id if the job started successfully, 0 if the job
///             table is full, -1 if the program could not be executed.
/// @return The job pointer if the job started successfully, NULL otherwise
Job *job_start(JobOptions opts, int *status)
{
  int i;
  Job *job;

  // Search for a free slot in the table
  for (i = 0; i < MAX_RUNNING_JOBS; i++) {
    if (table[i] == NULL) {
      break;
    }
  }

  if (i == MAX_RUNNING_JOBS) {
    // No free slots
    shell_free_argv(opts.argv);
    *status = 0;
    return NULL;
  }

  job = xmalloc(sizeof(Job));
  // Initialize
  job->id = i + 1;
  *status = job->id;
  job->status = -1;
  job->refcount = 1;
  job->stopped_time = 0;
  job->term_sent = false;
  job->in = NULL;
  job->out = NULL;
  job->err = NULL;
  job->opts = opts;
  job->closed = false;

  process_init(job);

  if (opts.writable) {
    handle_set_job((uv_handle_t *)job->proc_stdin, job);
    job->refcount++;
  }

  if (opts.stdout_cb) {
    handle_set_job((uv_handle_t *)job->proc_stdout, job);
    job->refcount++;
  }

  if (opts.stderr_cb) {
    handle_set_job((uv_handle_t *)job->proc_stderr, job);
    job->refcount++;
  }

  // Spawn the job
  if (!process_spawn(job)) {
    if (opts.writable) {
      uv_close((uv_handle_t *)job->proc_stdin, close_cb);
    }
    if (opts.stdout_cb) {
      uv_close((uv_handle_t *)job->proc_stdout, close_cb);
    }
    if (opts.stderr_cb) {
      uv_close((uv_handle_t *)job->proc_stderr, close_cb);
    }
    process_close(job);
    event_poll(0);
    // Manually invoke the close_cb to free the job resources
    *status = -1;
    return NULL;
  }

  if (opts.writable) {
    job->in = wstream_new(opts.maxmem);
    wstream_set_stream(job->in, job->proc_stdin);
  }

  // Start the readable streams
  if (opts.stdout_cb) {
    job->out = rstream_new(read_cb, rbuffer_new(JOB_BUFFER_SIZE), job);
    rstream_set_stream(job->out, job->proc_stdout);
    rstream_start(job->out);
  }

  if (opts.stderr_cb) {
    job->err = rstream_new(read_cb, rbuffer_new(JOB_BUFFER_SIZE), job);
    rstream_set_stream(job->err, job->proc_stderr);
    rstream_start(job->err);
  }
  // Save the job to the table
  table[i] = job;

  return job;
}
Exemple #5
0
void input_init(void)
{
  input_buffer = rbuffer_new(INPUT_BUFFER_SIZE + MAX_KEY_CODE_LEN);
}
Exemple #6
0
/// Tries to start a new job.
///
/// @param argv Argument vector for the process. The first item is the
///        executable to run.
/// @param data Caller data that will be associated with the job
/// @param stdout_cb Callback that will be invoked when data is available
///        on stdout
/// @param stderr_cb Callback that will be invoked when data is available
///        on stderr
/// @param job_exit_cb Callback that will be invoked when the job exits
/// @param maxmem Maximum amount of memory used by the job WStream
/// @param[out] status The job id if the job started successfully, 0 if the job
///             table is full, -1 if the program could not be executed.
/// @return The job pointer if the job started successfully, NULL otherwise
Job *job_start(char **argv,
               void *data,
               rstream_cb stdout_cb,
               rstream_cb stderr_cb,
               job_exit_cb job_exit_cb,
               size_t maxmem,
               int *status)
{
  int i;
  Job *job;

  // Search for a free slot in the table
  for (i = 0; i < MAX_RUNNING_JOBS; i++) {
    if (table[i] == NULL) {
      break;
    }
  }

  if (i == MAX_RUNNING_JOBS) {
    // No free slots
    *status = 0;
    return NULL;
  }

  job = xmalloc(sizeof(Job));
  // Initialize
  job->id = i + 1;
  *status = job->id;
  job->status = -1;
  job->pending_refs = 3;
  job->pending_closes = 4;
  job->data = data;
  job->stdout_cb = stdout_cb;
  job->stderr_cb = stderr_cb;
  job->exit_cb = job_exit_cb;
  job->stopped = false;
  job->exit_timeout = EXIT_TIMEOUT;
  job->proc_opts.file = argv[0];
  job->proc_opts.args = argv;
  job->proc_opts.stdio = job->stdio;
  job->proc_opts.stdio_count = 3;
  job->proc_opts.flags = UV_PROCESS_WINDOWS_HIDE;
  job->proc_opts.exit_cb = exit_cb;
  job->proc_opts.cwd = NULL;
  job->proc_opts.env = NULL;
  job->proc.data = NULL;
  job->proc_stdin.data = NULL;
  job->proc_stdout.data = NULL;
  job->proc_stderr.data = NULL;

  // Initialize the job std{in,out,err}
  uv_pipe_init(uv_default_loop(), &job->proc_stdin, 0);
  job->stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
  job->stdio[0].data.stream = (uv_stream_t *)&job->proc_stdin;

  uv_pipe_init(uv_default_loop(), &job->proc_stdout, 0);
  job->stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
  job->stdio[1].data.stream = (uv_stream_t *)&job->proc_stdout;

  uv_pipe_init(uv_default_loop(), &job->proc_stderr, 0);
  job->stdio[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
  job->stdio[2].data.stream = (uv_stream_t *)&job->proc_stderr;

  // Give all handles a reference to the job
  handle_set_job((uv_handle_t *)&job->proc, job);
  handle_set_job((uv_handle_t *)&job->proc_stdin, job);
  handle_set_job((uv_handle_t *)&job->proc_stdout, job);
  handle_set_job((uv_handle_t *)&job->proc_stderr, job);

  // Spawn the job
  if (uv_spawn(uv_default_loop(), &job->proc, &job->proc_opts) != 0) {
    free_job(job);
    *status = -1;
    return NULL;
  }

  job->in = wstream_new(maxmem);
  wstream_set_stream(job->in, (uv_stream_t *)&job->proc_stdin);
  // Start the readable streams
  job->out = rstream_new(read_cb, rbuffer_new(JOB_BUFFER_SIZE), job);
  job->err = rstream_new(read_cb, rbuffer_new(JOB_BUFFER_SIZE), job);
  rstream_set_stream(job->out, (uv_stream_t *)&job->proc_stdout);
  rstream_set_stream(job->err, (uv_stream_t *)&job->proc_stderr);
  rstream_start(job->out);
  rstream_start(job->err);
  // Save the job to the table
  table[i] = job;

  // Start polling job status if this is the first
  if (job_count == 0) {
    uv_prepare_start(&job_prepare, job_prepare_cb);
  }
  job_count++;

  return job;
}