Ejemplo n.º 1
0
/* Create a CGI bucket using pipes from script stdout 'out'
 * and stderr 'err', for request 'r'. */
static apr_bucket *cgi_bucket_create(request_rec *r,
                                     apr_file_t *out, apr_file_t *err,
                                     apr_bucket_alloc_t *list)
{
    apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
    apr_status_t rv;
    apr_pollfd_t fd;
    struct cgi_bucket_data *data = apr_palloc(r->pool, sizeof *data);

    APR_BUCKET_INIT(b);
    b->free = apr_bucket_free;
    b->list = list;
    b->type = &bucket_type_cgi;
    b->length = (apr_size_t)(-1);
    b->start = -1;

    /* Create the pollset */
    rv = apr_pollset_create(&data->pollset, 2, r->pool, 0);
    if (rv != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01217)
                     "apr_pollset_create(); check system or user limits");
        return NULL;
    }

    fd.desc_type = APR_POLL_FILE;
    fd.reqevents = APR_POLLIN;
    fd.p = r->pool;
    fd.desc.f = out; /* script's stdout */
    fd.client_data = (void *)1;
    rv = apr_pollset_add(data->pollset, &fd);
    if (rv != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01218)
                     "apr_pollset_add(); check system or user limits");
        return NULL;
    }

    fd.desc.f = err; /* script's stderr */
    fd.client_data = (void *)2;
    rv = apr_pollset_add(data->pollset, &fd);
    if (rv != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01219)
                     "apr_pollset_add(); check system or user limits");
        return NULL;
    }

    data->r = r;
    b->data = data;
    return b;
}
Ejemplo n.º 2
0
/** Create interruptable pollset on top of APR pollset */
APT_DECLARE(apt_pollset_t*) apt_pollset_create(apr_uint32_t size, apr_pool_t *pool)
{
	apt_pollset_t *pollset = apr_palloc(pool,sizeof(apt_pollset_t));
	pollset->pool = pool;
	memset(&pollset->wakeup_pfd,0,sizeof(pollset->wakeup_pfd));
	
	/* create pollset with max number of descriptors size+1, 
	where +1 is builtin wakeup descriptor */
	if(apr_pollset_create(&pollset->base,size+1,pool,0) != APR_SUCCESS) {
		return NULL;
	}

	/* create wakeup pipe */
	if(apt_wakeup_pipe_create(pollset) != TRUE) {
		apr_pollset_destroy(pollset->base);
		return NULL;
	}

	/* add wakeup pipe to pollset */
	if(apr_pollset_add(pollset->base,&pollset->wakeup_pfd) != APR_SUCCESS) {
		apt_wakeup_pipe_destroy(pollset);
		apr_pollset_destroy(pollset->base);
		return NULL;
	}
	return pollset;
}
Ejemplo n.º 3
0
int do_accept(apr_pollset_t *pollset, apr_socket_t *lsock, apr_pool_t *mp)
{
	apr_socket_t *ns;/* accepted socket */
	apr_status_t rv;
			
	rv = apr_socket_accept(&ns, lsock, mp);
	if (rv == APR_SUCCESS) {
		serv_ctx_t *serv_ctx = apr_palloc(mp, sizeof(serv_ctx_t));
		apr_pollfd_t pfd = { mp, APR_POLL_SOCKET, APR_POLLIN, 0, { NULL }, serv_ctx };
		pfd.desc.s = ns;
		/* at first, we expect requests, so we poll APR_POLLIN event */
		serv_ctx->status = SERV_RECV_REQUEST;
		serv_ctx->cb_func = recv_req_cb;
		serv_ctx->recv.is_firstline = TRUE;
		serv_ctx->mp = mp;

	/**
	 * non-blocking socket. We can't expect that @ns 
	 * inherits non-blocking mode from @lsock 
	 */
		apr_socket_opt_set(ns, APR_SO_NONBLOCK, 1);
		apr_socket_timeout_set(ns, 0);
		
		apr_pollset_add(pollset, &pfd);
	}
	return TRUE;
}
Ejemplo n.º 4
0
static apt_bool_t mrcp_client_agent_pollset_create(mrcp_connection_agent_t *agent)
{
	apr_status_t status;
	
	/* create pollset */
	status = apr_pollset_create(&agent->pollset, (apr_uint32_t)agent->max_connection_count + 1, agent->pool, 0);
	if(status != APR_SUCCESS) {
		apt_log(APT_PRIO_WARNING,"Failed to Create Pollset");
		return FALSE;
	}

	/* create control socket */
	if(mrcp_client_agent_control_socket_create(agent) != TRUE) {
		apt_log(APT_PRIO_WARNING,"Failed to Create Control Socket");
		apr_pollset_destroy(agent->pollset);
		return FALSE;
	}
	/* add control socket to pollset */
	agent->control_sock_pfd.desc_type = APR_POLL_SOCKET;
	agent->control_sock_pfd.reqevents = APR_POLLIN;
	agent->control_sock_pfd.desc.s = agent->control_sock;
	agent->control_sock_pfd.client_data = agent->control_sock;
	status = apr_pollset_add(agent->pollset, &agent->control_sock_pfd);
	if(status != APR_SUCCESS) {
		apt_log(APT_PRIO_WARNING,"Failed to Add Control Socket to Pollset");
		mrcp_client_agent_control_socket_destroy(agent);
		apr_pollset_destroy(agent->pollset);
		return FALSE;
	}

	return TRUE;
}
Ejemplo n.º 5
0
int poll_worker_update_job(
        poll_worker_t *worker,
        poll_job_t *job,
        int mode) {
    if (job->pfd.reqevents == mode) {
	return 0;
    }

    //    SAFE_ASSERT(job->ps != NULL);
    if(job->ps == NULL) {
	return -1;
    }

    SAFE_ASSERT(worker != NULL);

    apr_status_t status = 0;
    status = apr_pollset_remove(worker->ps, &job->pfd);   
    if (status != APR_SUCCESS) {
	LOG_ERROR("error in remove from pollset. code: %d, message: %s",
		  (int)status, apr_strerror(status, malloc(100), 100));
	SAFE_ASSERT(0);
    }
    
    job->pfd.reqevents = mode;
    status = apr_pollset_add(worker->ps, &job->pfd);
    if (status != APR_SUCCESS) {
	LOG_ERROR("error in readd to pollset. code: %d, message: %s",
		  (int) status, apr_strerror(status, malloc(100), 100));
    }
    return 0;
}
Ejemplo n.º 6
0
static int do_accept(serv_ctx_t *serv_ctx, apr_pollset_t *pollset, apr_socket_t *lsock, apr_pool_t *mp)
{
    apr_socket_t *ns;/* accepted socket */

    apr_status_t rv = apr_socket_accept(&ns, lsock, mp);
    if (rv == APR_SUCCESS)
    {
        //serv_ctx_t *serv_ctx = apr_palloc(mp, sizeof(serv_ctx_t));
        serv_ctx->up_buf_level = 0;
        serv_ctx->down_buf_level = 0;
        serv_ctx->channel_state = connected;


        apr_pollfd_t pfd = { mp, APR_POLL_SOCKET, APR_POLLIN|APR_POLLOUT|APR_POLLHUP, 0, { NULL }, serv_ctx };
        pfd.desc.s = ns;
        serv_ctx->mp = mp;

        /* non-blocking socket. We can't expect that @ns inherits non-blocking mode from @lsock */
        apr_socket_opt_set(ns, APR_SO_NONBLOCK, 1); //Setup socket options for the specified socket
        apr_socket_timeout_set(ns, 0);

        apr_pollset_add(pollset, &pfd); //Add a socket or file descriptor to a pollset

        //printf("connected client to channel %d\n", serv_ctx->channel_number);
    }
    return TRUE;
}
Ejemplo n.º 7
0
static apr_status_t pollset_add(void *user_baton,
                                apr_pollfd_t *pfd,
                                void *serf_baton)
{
    serf_pollset_t *s = (serf_pollset_t*)user_baton;
    pfd->client_data = serf_baton;
    return apr_pollset_add(s->pollset, pfd);
}
Ejemplo n.º 8
0
SWITCH_DECLARE(switch_status_t) switch_pollset_add(switch_pollset_t *pollset, const switch_pollfd_t *descriptor)
{
	if (!pollset || !descriptor) {
		return SWITCH_STATUS_FALSE;
	}

	return apr_pollset_add((apr_pollset_t *) pollset, (const apr_pollfd_t *) descriptor);
}
Ejemplo n.º 9
0
/**
 * do_listen -- create a listen socket
 */
apr_status_t do_listen(apr_pollset_t *pollset, apr_hash_t *ht, 
		       apr_pool_t *mp, const char *param)
{
	apr_status_t rv;
	apr_socket_t *s;
	apr_sockaddr_t *sa;
	char **ptr;
	int port;
	
	ptr = str_split_char(param, ":");
	if (ptr == NULL) {
		fprintf(stderr, "Get Null param!\n");
		return APR_EINVAL;
	}
	// then convert param
	port = atoi(ptr[1]);
	if (port < 0)
		return APR_EINVAL;

	rv = apr_sockaddr_info_get(&sa, ptr[0], APR_INET, port, 0, mp);
	if (rv != APR_SUCCESS) {
		return rv;
	}
	
	rv = apr_socket_create(&s, sa->family, SOCK_STREAM, APR_PROTO_TCP, mp);
	if (rv != APR_SUCCESS) {
		return rv;
	}

	/* non-blocking socket */
	apr_socket_opt_set(s, APR_SO_NONBLOCK, 1);
	apr_socket_timeout_set(s, 0);
	apr_socket_opt_set(s, APR_SO_REUSEADDR, 1);/* this is useful for a 
						* server(socket listening) process */

	rv = apr_socket_bind(s, sa);
	if (rv != APR_SUCCESS) {
		return rv;
	}
	rv = apr_socket_listen(s, DEF_SOCKET_BACKLOG);
	if (rv != APR_SUCCESS) {
		return rv;
	}
	// Then.., add it to hash table, listen and connect socket 
	// against a different val, so we can distinguish in the 
	// pollset
	apr_hash_set(ht, s, APR_HASH_KEY_STRING, "S"); // server

	// Then.., if everything is OK, add it to the pollset
	apr_pollfd_t pfd = {mp, APR_POLL_SOCKET, APR_POLLIN, 0, {NULL}, NULL};
	pfd.desc.s = s;
	apr_pollset_add(pollset, &pfd);
	free(ptr);

	return APR_SUCCESS;
	
}
Ejemplo n.º 10
0
/**
 * thread-safe on different jobs at the same worker.
 */
int poll_worker_add_job(
        poll_worker_t *worker,
        poll_job_t *job) {
    SAFE_ASSERT(worker != NULL);
    SAFE_ASSERT(job->ps == NULL);
    SAFE_ASSERT(apr_pollset_add(worker->ps, &job->pfd) == APR_SUCCESS);  
    job->ps = worker->ps;
    return 0;
}
Ejemplo n.º 11
0
apr_status_t apr_wait_for_io_or_timeout(apr_file_t *f, apr_socket_t *s,
                                        int for_read)
{
    apr_interval_time_t timeout;
    apr_pollfd_t pfd;
    int type = for_read ? APR_POLLIN : APR_POLLOUT;
    apr_pollset_t *pollset;
    apr_status_t status;

    /* TODO - timeout should be less each time through this loop */
    if (f) {
        pfd.desc_type = APR_POLL_FILE;
        pfd.desc.f = f;

        pollset = f->pollset;
        if (pollset == NULL) {
            status = apr_pollset_create(&(f->pollset), 1, f->pool, 0);
            if (status != APR_SUCCESS) {
                return status;
            }
            pollset = f->pollset;
        }
        timeout = f->timeout;
    }
    else {
        pfd.desc_type = APR_POLL_SOCKET;
        pfd.desc.s = s;

        pollset = s->pollset;
        timeout = s->timeout;
    }
    pfd.reqevents = type;

    /* Remove the object if it was in the pollset, then add in the new
     * object with the correct reqevents value. Ignore the status result
     * on the remove, because it might not be in there (yet).
     */
    (void) apr_pollset_remove(pollset, &pfd);

    /* ### check status code */
    (void) apr_pollset_add(pollset, &pfd);

    do {
        int numdesc;
        const apr_pollfd_t *pdesc;

        status = apr_pollset_poll(pollset, timeout, &numdesc, &pdesc);

        if (numdesc == 1 && (pdesc[0].rtnevents & type) != 0) {
            return APR_SUCCESS;
        }
    } while (APR_STATUS_IS_EINTR(status));

    return status;
}
Ejemplo n.º 12
0
static void multi_event_pollset(abts_case *tc, void *data)
{
    apr_status_t rv;
    apr_pollfd_t socket_pollfd;
    int lrv;
    const apr_pollfd_t *descs = NULL;

    ABTS_PTR_NOTNULL(tc, s[0]);
    socket_pollfd.desc_type = APR_POLL_SOCKET;
    socket_pollfd.reqevents = APR_POLLIN | APR_POLLOUT;
    socket_pollfd.desc.s = s[0];
    socket_pollfd.client_data = s[0];
    rv = apr_pollset_add(pollset, &socket_pollfd);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);

    send_msg(s, sa, 0, tc);

    rv = apr_pollset_poll(pollset, -1, &lrv, &descs);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    if (lrv == 1) {
        int ev = descs[0].rtnevents;
        ABTS_PTR_EQUAL(tc, s[0], descs[0].desc.s);
        ABTS_PTR_EQUAL(tc, s[0],  descs[0].client_data);
        ABTS_ASSERT(tc, "either or both of APR_POLLIN, APR_POLLOUT returned",
                    ((ev & APR_POLLIN) != 0) || ((ev & APR_POLLOUT) != 0));
    }
    else if (lrv == 2) {
        ABTS_PTR_EQUAL(tc, s[0], descs[0].desc.s);
        ABTS_PTR_EQUAL(tc, s[0], descs[0].client_data);
        ABTS_PTR_EQUAL(tc, s[0], descs[1].desc.s);
        ABTS_PTR_EQUAL(tc, s[0], descs[1].client_data);
        ABTS_ASSERT(tc, "returned events incorrect",
                    ((descs[0].rtnevents | descs[1].rtnevents)
                     == (APR_POLLIN | APR_POLLOUT))
                    && descs[0].rtnevents != descs[1].rtnevents);
    }
    else {
        ABTS_ASSERT(tc, "either one or two events returned",
                    lrv == 1 || lrv == 2);
    }

    recv_msg(s, 0, p, tc);

    rv = apr_pollset_poll(pollset, 0, &lrv, &descs);
    ABTS_INT_EQUAL(tc, 0, APR_STATUS_IS_TIMEUP(rv));
    ABTS_INT_EQUAL(tc, 1, lrv);
    ABTS_PTR_EQUAL(tc, s[0], descs[0].desc.s);
    ABTS_INT_EQUAL(tc, APR_POLLOUT, descs[0].rtnevents);
    ABTS_PTR_EQUAL(tc, s[0],  descs[0].client_data);

    rv = apr_pollset_remove(pollset, &socket_pollfd);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
}
Ejemplo n.º 13
0
void LLPumpIO::rebuildPollset()
{
	LLMemType m1(LLMemType::MTYPE_IO_PUMP);
//	lldebugs << "LLPumpIO::rebuildPollset()" << llendl;
	if(mPollset)
	{
		//lldebugs << "destroying pollset" << llendl;
		apr_pollset_destroy(mPollset);
		mPollset = NULL;
	}
	U32 size = 0;
	running_chains_t::iterator run_it = mRunningChains.begin();
	running_chains_t::iterator run_end = mRunningChains.end();
	for(; run_it != run_end; ++run_it)
	{
		size += (*run_it).mDescriptors.size();
	}
	//lldebugs << "found " << size << " descriptors." << llendl;
	if(size)
	{
		// Recycle the memory pool
		const S32 POLLSET_POOL_RECYCLE_COUNT = 100;
		if(mCurrentPool
		   && (0 == (++mCurrentPoolReallocCount % POLLSET_POOL_RECYCLE_COUNT)))
		{
			apr_pool_destroy(mCurrentPool);
			mCurrentPool = NULL;
			mCurrentPoolReallocCount = 0;
		}
		if(!mCurrentPool)
		{
			apr_status_t status = apr_pool_create(&mCurrentPool, mPool);
			(void)ll_apr_warn_status(status);
		}

		// add all of the file descriptors
		run_it = mRunningChains.begin();
		LLChainInfo::conditionals_t::iterator fd_it;
		LLChainInfo::conditionals_t::iterator fd_end;
		apr_pollset_create(&mPollset, size, mCurrentPool, 0);
		for(; run_it != run_end; ++run_it)
		{
			fd_it = (*run_it).mDescriptors.begin();
			fd_end = (*run_it).mDescriptors.end();
			for(; fd_it != fd_end; ++fd_it)
			{
				apr_pollset_add(mPollset, &((*fd_it).second));
			}
		}
	}
}
/* Create a CGI bucket using pipes from script stdout 'out'
 * and stderr 'err', for request 'r'. */
static apr_bucket *cgi_bucket_create(request_rec *r,
                                     apr_file_t *out, apr_file_t *err,
                                     apr_bucket_alloc_t *list)
{
    apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
    apr_status_t rv;
    apr_pollfd_t fd;
    struct cgi_bucket_data *data = apr_palloc(r->pool, sizeof *data);

    APR_BUCKET_INIT(b);
    b->free = apr_bucket_free;
    b->list = list;
    b->type = &bucket_type_cgi;
    b->length = (apr_size_t)(-1);
    b->start = -1;

    /* Create the pollset */
    rv = apr_pollset_create(&data->pollset, 2, r->pool, 0);
    AP_DEBUG_ASSERT(rv == APR_SUCCESS);

    fd.desc_type = APR_POLL_FILE;
    fd.reqevents = APR_POLLIN;
    fd.p = r->pool;
    fd.desc.f = out; /* script's stdout */
    fd.client_data = (void *)1;
    rv = apr_pollset_add(data->pollset, &fd);
    AP_DEBUG_ASSERT(rv == APR_SUCCESS);

    fd.desc.f = err; /* script's stderr */
    fd.client_data = (void *)2;
    rv = apr_pollset_add(data->pollset, &fd);
    AP_DEBUG_ASSERT(rv == APR_SUCCESS);

    data->r = r;
    b->data = data;
    return b;
}
Ejemplo n.º 15
0
static apt_bool_t mrcp_server_agent_connection_accept(mrcp_connection_agent_t *agent)
{
	apr_socket_t *sock;
	apr_pool_t *pool;
	mrcp_connection_t *connection;

	if(!agent->null_connection) {
		apr_pool_create(&pool,NULL);
		if(apr_socket_accept(&sock,agent->listen_sock,pool) != APR_SUCCESS) {
			return FALSE;
		}
		apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Rejected TCP/MRCPv2 Connection");
		apr_socket_close(sock);
		apr_pool_destroy(pool);
		return FALSE;
	}

	pool = agent->null_connection->pool;
	if(apr_socket_accept(&sock,agent->listen_sock,pool) != APR_SUCCESS) {
		return FALSE;
	}

	connection = mrcp_connection_create();
	connection->sock = sock;
	connection->sock_pfd.desc_type = APR_POLL_SOCKET;
	connection->sock_pfd.reqevents = APR_POLLIN;
	connection->sock_pfd.desc.s = connection->sock;
	connection->sock_pfd.client_data = connection;
	if(apr_pollset_add(agent->pollset, &connection->sock_pfd) != APR_SUCCESS) {
		apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Add to Pollset");
		apr_socket_close(sock);
		mrcp_connection_destroy(connection);
		return FALSE;
	}

	connection->agent = agent;
	connection->it = apt_list_push_back(agent->connection_list,connection);
	connection->parser = mrcp_parser_create(agent->resource_factory,connection->pool);
	connection->generator = mrcp_generator_create(agent->resource_factory,connection->pool);

	apr_socket_addr_get(&connection->sockaddr,APR_REMOTE,sock);
	if(apr_sockaddr_ip_get(&connection->remote_ip.buf,connection->sockaddr) == APR_SUCCESS) {
		connection->remote_ip.length = strlen(connection->remote_ip.buf);
	}
	apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Accepted TCP/MRCPv2 Connection %s:%d",
			connection->remote_ip.buf,
			connection->sockaddr->port);
	return TRUE;
}
Ejemplo n.º 16
0
/* Create a dummy wakeup socket pipe for interrupting the poller
 */
static apr_status_t create_wakeup_pipe(apr_pollset_t *pollset)
{
    apr_status_t rv;

    if ((rv = apr_file_socket_pipe_create(&pollset->wakeup_pipe[0],
                                          &pollset->wakeup_pipe[1],
                                          pollset->pool)) != APR_SUCCESS)
        return rv;

    pollset->wakeup_pfd.p = pollset->pool;
    pollset->wakeup_pfd.reqevents = APR_POLLIN;
    pollset->wakeup_pfd.desc_type = APR_POLL_FILE;
    pollset->wakeup_pfd.desc.f = pollset->wakeup_pipe[0];

    return apr_pollset_add(pollset, &pollset->wakeup_pfd);
}
Ejemplo n.º 17
0
static mrcp_connection_t* mrcp_client_agent_connection_create(mrcp_connection_agent_t *agent, mrcp_control_descriptor_t *descriptor)
{
	mrcp_connection_t *connection = mrcp_connection_create();

	connection->remote_ip = descriptor->ip;
	apr_sockaddr_info_get(&connection->sockaddr,descriptor->ip.buf,APR_INET,descriptor->port,0,connection->pool);
	if(!connection->sockaddr) {
		mrcp_connection_destroy(connection);
		return NULL;
	}

	if(apr_socket_create(&connection->sock, connection->sockaddr->family, SOCK_STREAM, APR_PROTO_TCP, connection->pool) != APR_SUCCESS) {
		mrcp_connection_destroy(connection);
		return NULL;
	}

	apr_socket_opt_set(connection->sock, APR_SO_NONBLOCK, 0);
	apr_socket_timeout_set(connection->sock, -1);
	apr_socket_opt_set(connection->sock, APR_SO_REUSEADDR, 1);

	if(apr_socket_connect(connection->sock, connection->sockaddr) != APR_SUCCESS) {
		apr_socket_close(connection->sock);
		mrcp_connection_destroy(connection);
		return NULL;
	}

	connection->sock_pfd.desc_type = APR_POLL_SOCKET;
	connection->sock_pfd.reqevents = APR_POLLIN;
	connection->sock_pfd.desc.s = connection->sock;
	connection->sock_pfd.client_data = connection;
	if(apr_pollset_add(agent->pollset, &connection->sock_pfd) != APR_SUCCESS) {
		apr_socket_close(connection->sock);
		mrcp_connection_destroy(connection);
		return NULL;
	}
	
	apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Established TCP/MRCPv2 Connection %s:%d",
			connection->remote_ip.buf,
			connection->sockaddr->port);
	connection->agent = agent;
	connection->it = apt_list_push_back(agent->connection_list,connection);
	connection->parser = mrcp_parser_create(agent->resource_factory,connection->pool);
	connection->generator = mrcp_generator_create(agent->resource_factory,connection->pool);
	return connection;
}
Ejemplo n.º 18
0
static void add_sockets_pollset(CuTest *tc)
{
    apr_status_t rv;
    int i;

    for (i = 0; i < LARGE_NUM_SOCKETS;i++){
        apr_pollfd_t socket_pollfd;

        CuAssertPtrNotNull(tc, s[i]);

        socket_pollfd.desc_type = APR_POLL_SOCKET;
        socket_pollfd.reqevents = APR_POLLIN;
        socket_pollfd.desc.s = s[i];
        socket_pollfd.client_data = s[i];
        rv = apr_pollset_add(pollset, &socket_pollfd);
        CuAssertIntEquals(tc, APR_SUCCESS, rv);
    }
}
Ejemplo n.º 19
0
apr_status_t sspdy_spdy_tls_update_pollset(sspdy_connection_t *conn,
                                           apr_pollset_t *pollset)
{
    tls_conn_ctx_t *ctx = conn->data;
    apr_pollfd_t pfd = { 0 };

    pfd.desc_type = APR_POLL_SOCKET;
    pfd.desc.s = ctx->skt;
    pfd.client_data = conn;
    pfd.reqevents = APR_POLLIN | APR_POLLHUP | APR_POLLERR;

    if (!ctx->flags & FLAG_STOP_WRITING) {

        pfd.reqevents |= APR_POLLOUT;
    }

    return apr_pollset_add(pollset, &pfd);
}
Ejemplo n.º 20
0
static void add_sockets_pollset(abts_case *tc, void *data)
{
    apr_status_t rv;
    int i;

    for (i = 0; i < LARGE_NUM_SOCKETS;i++){
        apr_pollfd_t socket_pollfd;

        ABTS_PTR_NOTNULL(tc, s[i]);

        socket_pollfd.desc_type = APR_POLL_SOCKET;
        socket_pollfd.reqevents = APR_POLLIN;
        socket_pollfd.desc.s = s[i];
        socket_pollfd.client_data = s[i];
        rv = apr_pollset_add(pollset, &socket_pollfd);
        ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    }
}
Ejemplo n.º 21
0
static void pollset_wakeup(abts_case *tc, void *data)
{
    apr_status_t rv;
    apr_pollfd_t socket_pollfd;
    apr_pollset_t *pollset;
    apr_int32_t num;
    const apr_pollfd_t *descriptors;

    rv = apr_pollset_create_ex(&pollset, 1, p, APR_POLLSET_WAKEABLE,
                               default_pollset_impl);
    if (rv == APR_ENOTIMPL) {
        ABTS_NOT_IMPL(tc, "apr_pollset_wakeup() not supported");
        return;
    }
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);

    /* send wakeup but no data; apr_pollset_poll() should return APR_EINTR */
    rv = apr_pollset_wakeup(pollset);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);

    rv = apr_pollset_poll(pollset, -1, &num, &descriptors);
    ABTS_INT_EQUAL(tc, APR_EINTR, rv);

    /* send wakeup and data; apr_pollset_poll() should return APR_SUCCESS */
    socket_pollfd.desc_type = APR_POLL_SOCKET;
    socket_pollfd.reqevents = APR_POLLIN;
    socket_pollfd.desc.s = s[0];
    socket_pollfd.client_data = s[0];
    rv = apr_pollset_add(pollset, &socket_pollfd);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);

    send_msg(s, sa, 0, tc);

    rv = apr_pollset_wakeup(pollset);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);

    rv = apr_pollset_poll(pollset, -1, &num, &descriptors);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    ABTS_INT_EQUAL(tc, 1, num);
}
Ejemplo n.º 22
0
/* Create a dummy wakeup pipe for interrupting the poller
 */
static apr_status_t create_wakeup_pipe(apr_pollset_t *pollset)
{
    apr_status_t rv;

    if ((rv = apr_file_pipe_create(&pollset->wakeup_pipe[0],
                                   &pollset->wakeup_pipe[1],
                                   pollset->pool)) != APR_SUCCESS)
        return rv;

    pollset->wakeup_pfd.p = pollset->pool;
    pollset->wakeup_pfd.reqevents = APR_POLLIN;
    pollset->wakeup_pfd.desc_type = APR_POLL_FILE;
    pollset->wakeup_pfd.desc.f = pollset->wakeup_pipe[0];

    {
        int flags;

        if ((flags = fcntl(pollset->wakeup_pipe[0]->filedes, F_GETFD)) == -1)
            return errno;

        flags |= FD_CLOEXEC;
        if (fcntl(pollset->wakeup_pipe[0]->filedes, F_SETFD, flags) == -1)
            return errno;
    }
    {
        int flags;

        if ((flags = fcntl(pollset->wakeup_pipe[1]->filedes, F_GETFD)) == -1)
            return errno;

        flags |= FD_CLOEXEC;
        if (fcntl(pollset->wakeup_pipe[1]->filedes, F_SETFD, flags) == -1)
            return errno;
    }

    return apr_pollset_add(pollset, &pollset->wakeup_pfd);
}
Ejemplo n.º 23
0
int sock_listen(net_sock_t *nsock, int max_pending)
{
    int err;
    network_sock_t *sock = (network_sock_t *)nsock;

    if (sock == NULL) return(1);

    err = apr_socket_listen(sock->fd, max_pending);
    if (err != APR_SUCCESS) return(err);

    //** Create the polling info
    apr_pollset_create(&(sock->pollset), 1, sock->mpool, APR_POLLSET_THREADSAFE);
//  sock->pfd = { sock->mpool, APR_POLL_SOCKET, APR_POLLIN, 0, { NULL }, NULL };
    sock->pfd.p = sock->mpool;
    sock->pfd.desc_type = APR_POLL_SOCKET;
    sock->pfd.reqevents = APR_POLLIN;
    sock->pfd.rtnevents = 0;
    sock->pfd.desc.s = sock->fd;
    sock->pfd.client_data = NULL;

    apr_pollset_add(sock->pollset, &(sock->pfd));

    return(0);
}
Ejemplo n.º 24
0
void ap_mpm_child_main(apr_pool_t *pconf)
{
    ap_listen_rec *lr = NULL;
    int requests_this_child = 0;
    int rv = 0;
    unsigned long ulTimes;
    int my_pid = getpid();
    ULONG rc, c;
    HQUEUE workq;
    apr_pollset_t *pollset;
    int num_listeners;
    TID server_maint_tid;
    void *sb_mem;

    /* Stop Ctrl-C/Ctrl-Break signals going to child processes */
    DosSetSignalExceptionFocus(0, &ulTimes);
    set_signals();

    /* Create pool for child */
    apr_pool_create(&pchild, pconf);

    ap_run_child_init(pchild, ap_server_conf);

    /* Create an event semaphore used to trigger other threads to shutdown */
    rc = DosCreateEventSem(NULL, &shutdown_event, 0, FALSE);

    if (rc) {
        ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf,
                     "unable to create shutdown semaphore, exiting");
        clean_child_exit(APEXIT_CHILDFATAL);
    }

    /* Gain access to the scoreboard. */
    rc = DosGetNamedSharedMem(&sb_mem, ap_scoreboard_fname,
                              PAG_READ|PAG_WRITE);

    if (rc) {
        ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf,
                     "scoreboard not readable in child, exiting");
        clean_child_exit(APEXIT_CHILDFATAL);
    }

    ap_calc_scoreboard_size();
    ap_init_scoreboard(sb_mem);

    /* Gain access to the accpet mutex */
    rc = DosOpenMutexSem(NULL, &ap_mpm_accept_mutex);

    if (rc) {
        ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf,
                     "accept mutex couldn't be accessed in child, exiting");
        clean_child_exit(APEXIT_CHILDFATAL);
    }

    /* Find our pid in the scoreboard so we know what slot our parent allocated us */
    for (child_slot = 0; ap_scoreboard_image->parent[child_slot].pid != my_pid && child_slot < HARD_SERVER_LIMIT; child_slot++);

    if (child_slot == HARD_SERVER_LIMIT) {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
                     "child pid not found in scoreboard, exiting");
        clean_child_exit(APEXIT_CHILDFATAL);
    }

    ap_my_generation = ap_scoreboard_image->parent[child_slot].generation;
    memset(ap_scoreboard_image->servers[child_slot], 0, sizeof(worker_score) * HARD_THREAD_LIMIT);

    /* Set up an OS/2 queue for passing connections & termination requests
     * to worker threads
     */
    rc = DosCreateQueue(&workq, QUE_FIFO, apr_psprintf(pchild, "/queues/httpd/work.%d", my_pid));

    if (rc) {
        ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf,
                     "unable to create work queue, exiting");
        clean_child_exit(APEXIT_CHILDFATAL);
    }

    /* Create initial pool of worker threads */
    for (c = 0; c < ap_min_spare_threads; c++) {
//        ap_scoreboard_image->servers[child_slot][c].tid = _beginthread(worker_main, NULL, 128*1024, (void *)c);
    }

    /* Start maintenance thread */
    server_maint_tid = _beginthread(server_maintenance, NULL, 32768, NULL);

    /* Set up poll */
    for (num_listeners = 0, lr = ap_listeners; lr; lr = lr->next) {
        num_listeners++;
    }

    apr_pollset_create(&pollset, num_listeners, pchild, 0);

    for (lr = ap_listeners; lr != NULL; lr = lr->next) {
        apr_pollfd_t pfd = { 0 };

        pfd.desc_type = APR_POLL_SOCKET;
        pfd.desc.s = lr->sd;
        pfd.reqevents = APR_POLLIN;
        pfd.client_data = lr;
        apr_pollset_add(pollset, &pfd);
    }

    /* Main connection accept loop */
    do {
        apr_pool_t *pconn;
        worker_args_t *worker_args;
        int last_poll_idx = 0;

        apr_pool_create(&pconn, pchild);
        worker_args = apr_palloc(pconn, sizeof(worker_args_t));
        worker_args->pconn = pconn;

        if (num_listeners == 1) {
            rv = apr_socket_accept(&worker_args->conn_sd, ap_listeners->sd, pconn);
        } else {
            const apr_pollfd_t *poll_results;
            apr_int32_t num_poll_results;

            rc = DosRequestMutexSem(ap_mpm_accept_mutex, SEM_INDEFINITE_WAIT);

            if (shutdown_pending) {
                DosReleaseMutexSem(ap_mpm_accept_mutex);
                break;
            }

            rv = APR_FROM_OS_ERROR(rc);

            if (rv == APR_SUCCESS) {
                rv = apr_pollset_poll(pollset, -1, &num_poll_results, &poll_results);
                DosReleaseMutexSem(ap_mpm_accept_mutex);
            }

            if (rv == APR_SUCCESS) {
                if (last_poll_idx >= num_listeners) {
                    last_poll_idx = 0;
                }

                lr = poll_results[last_poll_idx++].client_data;
                rv = apr_socket_accept(&worker_args->conn_sd, lr->sd, pconn);
                last_poll_idx++;
            }
        }

        if (rv != APR_SUCCESS) {
            if (!APR_STATUS_IS_EINTR(rv)) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
                             "apr_socket_accept");
                clean_child_exit(APEXIT_CHILDFATAL);
            }
        } else {
            DosWriteQueue(workq, WORKTYPE_CONN, sizeof(worker_args_t), worker_args, 0);
            requests_this_child++;
        }

        if (ap_max_requests_per_child != 0 && requests_this_child >= ap_max_requests_per_child)
            break;
    } while (!shutdown_pending && ap_my_generation == ap_scoreboard_image->global->running_generation);

    ap_scoreboard_image->parent[child_slot].quiescing = 1;
    DosPostEventSem(shutdown_event);
    DosWaitThread(&server_maint_tid, DCWW_WAIT);

    if (is_graceful) {
        char someleft;

        /* tell our worker threads to exit */
        for (c=0; c<HARD_THREAD_LIMIT; c++) {
            if (ap_scoreboard_image->servers[child_slot][c].status != SERVER_DEAD) {
                DosWriteQueue(workq, WORKTYPE_EXIT, 0, NULL, 0);
            }
        }

        do {
            someleft = 0;

            for (c=0; c<HARD_THREAD_LIMIT; c++) {
                if (ap_scoreboard_image->servers[child_slot][c].status != SERVER_DEAD) {
                    someleft = 1;
                    DosSleep(1000);
                    break;
                }
            }
        } while (someleft);
    } else {
        DosPurgeQueue(workq);

        for (c=0; c<HARD_THREAD_LIMIT; c++) {
            if (ap_scoreboard_image->servers[child_slot][c].status != SERVER_DEAD) {
                DosKillThread(ap_scoreboard_image->servers[child_slot][c].tid);
            }
        }
    }

    apr_pool_destroy(pchild);
}
Ejemplo n.º 25
0
int jtagHostLoop()
{


    apr_status_t rv;
    apr_pool_t *mp;
    apr_pollset_t *pollset;
    apr_int32_t num;
    const apr_pollfd_t *ret_pfd;

    apr_initialize();
    apr_pool_create(&mp, NULL);

    serv_ctx_t *channel_contexts[IPDBG_CHANNELS];


    apr_pollset_create(&pollset, DEF_POLLSET_NUM, mp, 0);
    for(uint8_t ch = 0; ch < IPDBG_CHANNELS; ++ch)
    {
        serv_ctx_t *serv_ctx = apr_palloc(mp, sizeof(serv_ctx_t));
        channel_contexts[ch] = serv_ctx;
        serv_ctx->channel_number = ch;
        serv_ctx->channel_state = listening;
        serv_ctx->up_buf_level = 0;
        serv_ctx->down_buf_level = 0;

        if(ch == 0) serv_ctx->valid_mask = IPDBG_LA_VALID_MASK;
        if(ch == 1) serv_ctx->valid_mask = IPDBG_IOVIEW_VALID_MASK;
        if(ch == 2) serv_ctx->valid_mask = IPDBG_GDB_VALID_MASK;
        if(ch == 3) serv_ctx->valid_mask = IPDBG_WFG_VALID_MASK;

        apr_socket_t *listening_sock = create_listen_sock(mp, ch);
        assert(listening_sock);

        apr_pollfd_t pfd = { mp, APR_POLL_SOCKET, APR_POLLIN, 0, { NULL }, serv_ctx };
        pfd.desc.s = listening_sock;
        apr_pollset_add(pollset, &pfd);
    }

    // reset JtagCDC
    uint16_t val;
    ipdbgJTAGtransfer(&val, 0xf00);

    while (1)
    {
        size_t transfers = 0;
        for(size_t ch = 0 ; ch < IPDBG_CHANNELS ; ++ch)
        {
            for(size_t idx = 0 ; idx < channel_contexts[ch]->down_buf_level; ++idx)
            {
                uint16_t val;
                ipdbgJTAGtransfer(&val, channel_contexts[ch]->down_buf[idx] | channel_contexts[ch]->valid_mask);
                transfers++;

                distribute_to_up_buffer(val, channel_contexts);
            }
            channel_contexts[ch]->down_buf_level = 0;
        }
        for(size_t k = transfers ; k < MIN_TRANSFERS ; ++k)
        {
            uint16_t val;
            ipdbgJTAGtransfer(&val, 0x000);
            distribute_to_up_buffer(val, channel_contexts);
        }

        rv = apr_pollset_poll(pollset, DEF_POLL_TIMEOUT, &num, &ret_pfd);
        if (rv == APR_SUCCESS)
        {
            int i;
            /* scan the active sockets */
            for (i = 0; i < num; i++)
            {
                serv_ctx_t *serv_ctx = ret_pfd[i].client_data;
                if(serv_ctx)
                {
                    if (serv_ctx->channel_state == listening)
                    {
                        apr_socket_t *listening_sock = ret_pfd[i].desc.s;
                         /* the listen socket is readable. that indicates we accepted a new connection */
                        do_accept(serv_ctx, pollset, listening_sock, mp);
                        apr_socket_close(listening_sock);
                        apr_pollset_remove(pollset, &ret_pfd[i]);
                    }
                    else
                    {
                        int ret = TRUE;
                        if(ret_pfd[i].rtnevents & (APR_POLLIN | APR_POLLHUP))
                        {
                            ret = connection_rx_cb(serv_ctx, pollset, ret_pfd[i].desc.s);
                        }
                        else // (ret_pfd[i].rtnevents & APR_POLLOUT)
                        {
                            ret = connection_tx_cb(serv_ctx, pollset, ret_pfd[i].desc.s);
                        }
                        if (ret == FALSE)
                        {
                            //printf("closing connection %d", serv_ctx->channel_number);
                            apr_socket_t *sock = ret_pfd[i].desc.s;

                            apr_socket_close(sock);
                            apr_pollset_remove(pollset, &ret_pfd[i]);

                            apr_socket_t *listening_sock = create_listen_sock(mp, serv_ctx->channel_number);
                            serv_ctx->channel_state = listening;

                            apr_pollfd_t pfd = { mp, APR_POLL_SOCKET, APR_POLLIN, 0, { NULL }, serv_ctx };
                            pfd.desc.s = listening_sock;
                            apr_pollset_add(pollset, &pfd);
                        }
                    }
                }
            }
        }
    }

    return 0;
}
Ejemplo n.º 26
0
void* thread_socket_pipe_receiver(apr_thread_t* thd, void* data)
{
	frl_socket_pipe* pipe = (frl_socket_pipe*)data;

	apr_status_t state;

	apr_socket_t* listen_sock;
	apr_socket_create(&listen_sock, pipe->sock_addr->family, SOCK_STREAM, APR_PROTO_TCP, pipe->sockpool);
	apr_socket_opt_set(listen_sock, APR_SO_NONBLOCK, 1);
	apr_socket_timeout_set(listen_sock, 0);
	apr_socket_opt_set(listen_sock, APR_SO_REUSEADDR, 1);
	pipe->recv_state = apr_socket_bind(listen_sock, pipe->sock_addr);
	F_ERROR_IF_RUN(APR_SUCCESS != pipe->recv_state, return NULL, "[frl_socket_pipe::thread_socket_pipe_receiver]: Socket Binding Error: %d\n", pipe->recv_state);
	pipe->recv_state = apr_socket_listen(listen_sock, SOMAXCONN);
	F_ERROR_IF_RUN(APR_SUCCESS != pipe->recv_state, return NULL, "[frl_socket_pipe::thread_socket_pipe_receiver]: Socket Listen Error: %d\n", pipe->recv_state);
	apr_uint32_t hash;
	apr_pollset_t* pollset;
	apr_pollset_create(&pollset, pipe->replicate+2, pipe->sockpool, 0);
	apr_pollfd_t pfd = { pipe->sockpool, APR_POLL_SOCKET, APR_POLLIN, 0, { NULL }, NULL };
	pfd.desc.s = listen_sock;
	apr_pollset_add(pollset, &pfd);
	do {
		// the fun loop
		apr_int32_t total;
		const apr_pollfd_t* ret_pfd;
		pipe->recv_state = apr_pollset_poll(pollset, SOCKET_PIPE_POLL_TIMEOUT, &total, &ret_pfd);
		if (APR_SUCCESS == pipe->recv_state)
		{
			for (int i = 0; i < total; i++)
			{
				if (ret_pfd[i].desc.s == listen_sock)
				{
					apr_socket_t* accept_sock;
					state = apr_socket_accept(&accept_sock, listen_sock, pipe->sockpool);
					F_ERROR_IF_RUN(APR_SUCCESS != state, continue, "[frl_socket_pipe::thread_socket_pipe_receiver]: Socket Accept Error: %d\n", state);
					// accept connection, initiate recv
					frl_pipe_state_t* pipestate = (frl_pipe_state_t*)frl_slab_palloc(pipe->statepool);
					apr_pollfd_t pfd = { pipe->sockpool, APR_POLL_SOCKET, APR_POLLIN, 0, { NULL }, pipestate };
					pipestate->state = FRL_PIPE_READ_HEADER_START;
					pipestate->reader = (char*)&pipestate->header;
					pipestate->offset = 0;
					pipestate->size = SIZEOF_FRL_PIPE_HEADER_T;
					pfd.desc.s = accept_sock;
					apr_socket_opt_set(accept_sock, APR_SO_NONBLOCK, 1);
					apr_socket_timeout_set(accept_sock, 0);
					apr_pollset_add(pollset, &pfd);
				} else {
					if (ret_pfd[i].rtnevents & APR_POLLIN)
					{
						frl_pipe_state_t* pipestate = (frl_pipe_state_t*)ret_pfd[i].client_data;
						apr_size_t len_a = pipestate->size-pipestate->offset;
						state = apr_socket_recv(ret_pfd[i].desc.s, pipestate->reader, &len_a);
						pipestate->offset += len_a;
						pipestate->reader += len_a;
						// read buffer to reader
						if ((pipestate->offset >= pipestate->size)||(APR_STATUS_IS_EAGAIN(state)))
						{
							pipestate->offset = pipestate->size;
							PIPE_STATE_TO_COMPLETE(pipestate->state);
							// read complete, move state to complete
						} else if ((APR_STATUS_IS_EOF(state))||(len_a == 0)) {
							apr_pollfd_t pfd = { pipe->sockpool, APR_POLL_SOCKET, APR_POLLIN, 0, { NULL }, pipestate };
							pfd.desc.s = ret_pfd[i].desc.s;
							apr_pollset_remove(pollset, &pfd);
							frl_slab_pfree(pipestate);
							apr_socket_close(ret_pfd[i].desc.s);
							// remote error, close connection
							continue;
						}
						switch (pipestate->state)
						{
							case FRL_PIPE_READ_HEADER_COMPLETE:
							{
								// recv header (hash & size)
								pipestate->data.offset = 0;
								pipestate->data.size = pipestate->header.size;
								state = pipe->recv_before(&pipestate->data.buf, &pipestate->data.size);
								if (FRL_PROGRESS_IS_INTERRUPT(state))
								{
									apr_pollfd_t pfd = { pipe->sockpool, APR_POLL_SOCKET, APR_POLLIN, 0, { NULL }, pipestate };
									pfd.desc.s = ret_pfd[i].desc.s;
									apr_pollset_remove(pollset, &pfd);
									frl_slab_pfree(pipestate);
									apr_socket_close(ret_pfd[i].desc.s);
									continue;
								}
								pipestate->state = FRL_PIPE_READ_BLOCK_START;
								// start to read block (<= 4092 bytes each)
								pipestate->reader = pipestate->buffer;
								pipestate->offset = 0;
								if (pipestate->data.size < SIZEOF_FRL_PIPE_BLOCK_BUFFER)
									pipestate->size = pipestate->data.size+SIZEOF_FRL_PIPE_HEADER_T;
								else
									pipestate->size = SOCKET_PACKAGE_SIZE;
								break;
							}
							case FRL_PIPE_READ_BLOCK_COMPLETE:
							{
								// a block complete, move to data
								memcpy(pipestate->data.buf+pipestate->data.offset, &pipestate->block.start, pipestate->block.header.size);
								hash = hashlittle(&pipestate->block.start, pipestate->size-SIZEOF_FRL_PIPE_HEADER_T);
								if (hash != pipestate->block.header.hash)
								{
									// check the hash fingerprint of the block
									apr_pollfd_t pfd = { pipe->sockpool, APR_POLL_SOCKET, APR_POLLIN, 0, { NULL }, pipestate };
									pfd.desc.s = ret_pfd[i].desc.s;
									apr_pollset_remove(pollset, &pfd);
									frl_slab_pfree(pipestate);
									apr_socket_close(ret_pfd[i].desc.s);
									continue;
								}
								pipestate->data.offset += pipestate->block.header.size;
								if (pipestate->data.offset >= pipestate->data.size)
								{
									// finish read, report state to remote
									apr_pollfd_t pfd = { pipe->sockpool, APR_POLL_SOCKET, APR_POLLIN, 0, { NULL }, pipestate };
									pfd.desc.s = ret_pfd[i].desc.s;
									apr_pollset_remove(pollset, &pfd);
									hash = hashlittle(pipestate->data.buf, pipestate->data.size);
									if (hash != pipestate->header.hash)
									{
										// check hash fingerprint of all data
										frl_slab_pfree(pipestate);
										apr_socket_close(ret_pfd[i].desc.s);
									} else {
										pfd.reqevents = APR_POLLOUT;
										state = pipe->recv_after(pipestate->data.buf, pipestate->data.size);
										if (FRL_PROGRESS_IS_INTERRUPT(state))
										{
											frl_slab_pfree(pipestate);
											apr_socket_close(ret_pfd[i].desc.s);
										} else {
											pipestate->state = FRL_PIPE_SEND_HEADER_START;
											pipestate->reader = (char*)&pipestate->header;
											pipestate->offset = 0;
											pipestate->size = SIZEOF_FRL_PIPE_HEADER_T;
											apr_pollset_add(pollset, &pfd);
										}
									}
									continue;
								}
								// to start read successor block
								pipestate->state = FRL_PIPE_READ_BLOCK_START;
								pipestate->reader = pipestate->buffer;
								pipestate->offset = 0;
								if (pipestate->data.size-pipestate->data.offset < SIZEOF_FRL_PIPE_BLOCK_BUFFER)
									pipestate->size = pipestate->data.size-pipestate->data.offset+SIZEOF_FRL_PIPE_HEADER_T;
								else
									pipestate->size = SOCKET_PACKAGE_SIZE;
								break;
							}
							default:
								break;
						}
					} else if (ret_pfd[i].rtnevents & APR_POLLOUT) {
						// send report information, basic header
						frl_pipe_state_t* pipestate = (frl_pipe_state_t*)ret_pfd[i].client_data;
						apr_size_t len_a = pipestate->size-pipestate->offset;
						state = apr_socket_send(ret_pfd[i].desc.s, pipestate->reader, &len_a);
						pipestate->offset += len_a;
						pipestate->reader += len_a;
						if ((pipestate->offset >= pipestate->size)||(APR_STATUS_IS_EAGAIN(state)))
						{
							pipestate->offset = pipestate->size;
							PIPE_STATE_TO_COMPLETE(pipestate->state);
						} else if ((APR_STATUS_IS_EOF(state))||(len_a == 0)) {
							apr_pollfd_t pfd = { pipe->sockpool, APR_POLL_SOCKET, APR_POLLOUT, 0, { NULL }, pipestate };
							pfd.desc.s = ret_pfd[i].desc.s;
							apr_pollset_remove(pollset, &pfd);
							frl_slab_pfree(pipestate);
							apr_socket_close(ret_pfd[i].desc.s);
							continue;
						}
						switch (pipestate->state)
						{
							case FRL_PIPE_SEND_HEADER_COMPLETE:
							{
								// complete, return to listen state
								apr_pollfd_t pfd = { pipe->sockpool, APR_POLL_SOCKET, APR_POLLOUT, 0, { NULL }, pipestate };
								pfd.desc.s = ret_pfd[i].desc.s;
								apr_pollset_remove(pollset, &pfd);
								pfd.reqevents = APR_POLLIN;
								pipestate->state = FRL_PIPE_DISABLED;
								pipestate->reader = 0;
								pipestate->offset = 0;
								pipestate->size = 0;
								apr_pollset_add(pollset, &pfd);
								break;
							}
							default:
								break;
						}
					} else {
						// other errors, close connection
						frl_pipe_state_t* pipestate = (frl_pipe_state_t*)ret_pfd[i].client_data;
						apr_pollfd_t pfd = { pipe->sockpool, APR_POLL_SOCKET, APR_POLLIN | APR_POLLOUT, 0, { NULL }, pipestate };
						pfd.desc.s = ret_pfd[i].desc.s;
						apr_pollset_remove(pollset, &pfd);
						frl_slab_pfree(pipestate);
						apr_socket_close(ret_pfd[i].desc.s);
					}
				}
			}
		} else if (!APR_STATUS_IS_TIMEUP(pipe->recv_state)) {
Ejemplo n.º 27
0
/* CONNECT handler */
static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
                                 proxy_server_conf *conf,
                                 char *url, const char *proxyname,
                                 apr_port_t proxyport)
{
    apr_pool_t *p = r->pool;
    apr_socket_t *sock;
    apr_status_t err, rv;
    apr_size_t i, o, nbytes;
    char buffer[HUGE_STRING_LEN];
    apr_socket_t *client_socket = ap_get_module_config(r->connection->conn_config, &core_module);
    int failed;
    apr_pollset_t *pollset;
    apr_pollfd_t pollfd;
    const apr_pollfd_t *signalled;
    apr_int32_t pollcnt, pi;
    apr_int16_t pollevent;
    apr_sockaddr_t *uri_addr, *connect_addr;

    apr_uri_t uri;
    const char *connectname;
    int connectport = 0;

    /* is this for us? */
    if (r->method_number != M_CONNECT) {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
             "proxy: CONNECT: declining URL %s", url);
    return DECLINED;
    }
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
         "proxy: CONNECT: serving URL %s", url);


    /*
     * Step One: Determine Who To Connect To
     *
     * Break up the URL to determine the host to connect to
     */

    /* we break the URL into host, port, uri */
    if (APR_SUCCESS != apr_uri_parse_hostinfo(p, url, &uri)) {
    return ap_proxyerror(r, HTTP_BAD_REQUEST,
                 apr_pstrcat(p, "URI cannot be parsed: ", url, NULL));
    }

    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
         "proxy: CONNECT: connecting %s to %s:%d", url, uri.hostname, uri.port);

    /* do a DNS lookup for the destination host */
    err = apr_sockaddr_info_get(&uri_addr, uri.hostname, APR_UNSPEC, uri.port, 0, p);

    /* are we connecting directly, or via a proxy? */
    if (proxyname) {
    connectname = proxyname;
    connectport = proxyport;
        err = apr_sockaddr_info_get(&connect_addr, proxyname, APR_UNSPEC, proxyport, 0, p);
    }
    else {
    connectname = uri.hostname;
    connectport = uri.port;
    connect_addr = uri_addr;
    }
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
         "proxy: CONNECT: connecting to remote proxy %s on port %d", connectname, connectport);

    /* check if ProxyBlock directive on this host */
    if (OK != ap_proxy_checkproxyblock(r, conf, uri_addr)) {
    return ap_proxyerror(r, HTTP_FORBIDDEN,
                 "Connect to remote machine blocked");
    }

    /* Check if it is an allowed port */
    if (conf->allowed_connect_ports->nelts == 0) {
    /* Default setting if not overridden by AllowCONNECT */
    switch (uri.port) {
        case APR_URI_HTTPS_DEFAULT_PORT:
        case APR_URI_SNEWS_DEFAULT_PORT:
        break;
        default:
                /* XXX can we call ap_proxyerror() here to get a nice log message? */
        return HTTP_FORBIDDEN;
    }
    } else if(!allowed_port(conf, uri.port)) {
        /* XXX can we call ap_proxyerror() here to get a nice log message? */
    return HTTP_FORBIDDEN;
    }

    /*
     * Step Two: Make the Connection
     *
     * We have determined who to connect to. Now make the connection.
     */

    /* get all the possible IP addresses for the destname and loop through them
     * until we get a successful connection
     */
    if (APR_SUCCESS != err) {
    return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(p,
                             "DNS lookup failure for: ",
                             connectname, NULL));
    }

    /*
     * At this point we have a list of one or more IP addresses of
     * the machine to connect to. If configured, reorder this
     * list so that the "best candidate" is first try. "best
     * candidate" could mean the least loaded server, the fastest
     * responding server, whatever.
     *
     * For now we do nothing, ie we get DNS round robin.
     * XXX FIXME
     */
    failed = ap_proxy_connect_to_backend(&sock, "CONNECT", connect_addr,
                                         connectname, conf, r->server,
                                         r->pool);

    /* handle a permanent error from the above loop */
    if (failed) {
        if (proxyname) {
            return DECLINED;
        }
        else {
            return HTTP_BAD_GATEWAY;
        }
    }

    /*
     * Step Three: Send the Request
     *
     * Send the HTTP/1.1 CONNECT request to the remote server
     */

    /* we are acting as a tunnel - the output filter stack should
     * be completely empty, because when we are done here we are done completely.
     * We add the NULL filter to the stack to do this...
     */
    r->output_filters = NULL;
    r->connection->output_filters = NULL;


    /* If we are connecting through a remote proxy, we need to pass
     * the CONNECT request on to it.
     */
    if (proxyport) {
    /* FIXME: Error checking ignored.
     */
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
             "proxy: CONNECT: sending the CONNECT request to the remote proxy");
        nbytes = apr_snprintf(buffer, sizeof(buffer),
                  "CONNECT %s HTTP/1.0" CRLF, r->uri);
        apr_socket_send(sock, buffer, &nbytes);
        nbytes = apr_snprintf(buffer, sizeof(buffer),
                  "Proxy-agent: %s" CRLF CRLF, ap_get_server_banner());
        apr_socket_send(sock, buffer, &nbytes);
    }
    else {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
             "proxy: CONNECT: Returning 200 OK Status");
        nbytes = apr_snprintf(buffer, sizeof(buffer),
                  "HTTP/1.0 200 Connection Established" CRLF);
        ap_xlate_proto_to_ascii(buffer, nbytes);
        apr_socket_send(client_socket, buffer, &nbytes);
        nbytes = apr_snprintf(buffer, sizeof(buffer),
                  "Proxy-agent: %s" CRLF CRLF, ap_get_server_banner());
        ap_xlate_proto_to_ascii(buffer, nbytes);
        apr_socket_send(client_socket, buffer, &nbytes);
#if 0
        /* This is safer code, but it doesn't work yet.  I'm leaving it
         * here so that I can fix it later.
         */
        r->status = HTTP_OK;
        r->header_only = 1;
        apr_table_set(r->headers_out, "Proxy-agent: %s", ap_get_server_banner());
        ap_rflush(r);
#endif
    }

    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
         "proxy: CONNECT: setting up poll()");

    /*
     * Step Four: Handle Data Transfer
     *
     * Handle two way transfer of data over the socket (this is a tunnel).
     */

/*    r->sent_bodyct = 1;*/

    if ((rv = apr_pollset_create(&pollset, 2, r->pool, 0)) != APR_SUCCESS)
    {
    apr_socket_close(sock);
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
            "proxy: CONNECT: error apr_pollset_create()");
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    /* Add client side to the poll */
    pollfd.p = r->pool;
    pollfd.desc_type = APR_POLL_SOCKET;
    pollfd.reqevents = APR_POLLIN;
    pollfd.desc.s = client_socket;
    pollfd.client_data = NULL;
    apr_pollset_add(pollset, &pollfd);

    /* Add the server side to the poll */
    pollfd.desc.s = sock;
    apr_pollset_add(pollset, &pollfd);

    while (1) { /* Infinite loop until error (one side closes the connection) */
        if ((rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled)) != APR_SUCCESS) {
        apr_socket_close(sock);
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "proxy: CONNECT: error apr_poll()");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
#ifdef DEBUGGING
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                     "proxy: CONNECT: woke from select(), i=%d", pollcnt);
#endif

        for (pi = 0; pi < pollcnt; pi++) {
            const apr_pollfd_t *cur = &signalled[pi];

            if (cur->desc.s == sock) {
                pollevent = cur->rtnevents;
                if (pollevent & APR_POLLIN) {
#ifdef DEBUGGING
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                                 "proxy: CONNECT: sock was set");
#endif
                    nbytes = sizeof(buffer);
                    rv = apr_socket_recv(sock, buffer, &nbytes);
                    if (rv == APR_SUCCESS) {
                        o = 0;
                        i = nbytes;
                        while(i > 0)
                        {
                            nbytes = i;
    /* This is just plain wrong.  No module should ever write directly
     * to the client.  For now, this works, but this is high on my list of
     * things to fix.  The correct line is:
     * if ((nbytes = ap_rwrite(buffer + o, nbytes, r)) < 0)
     * rbb
     */
                            rv = apr_socket_send(client_socket, buffer + o, &nbytes);
                            if (rv != APR_SUCCESS)
                                break;
                            o += nbytes;
                            i -= nbytes;
                        }
                    }
                    else
                        break;
                }
                else if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP))
                    break;
            }
            else if (cur->desc.s == client_socket) {
                pollevent = cur->rtnevents;
                if (pollevent & APR_POLLIN) {
#ifdef DEBUGGING
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                                 "proxy: CONNECT: client was set");
#endif
                    nbytes = sizeof(buffer);
                    rv = apr_socket_recv(client_socket, buffer, &nbytes);
                    if (rv == APR_SUCCESS) {
                        o = 0;
                        i = nbytes;
#ifdef DEBUGGING
                        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                                     "proxy: CONNECT: read %d from client", i);
#endif
                        while(i > 0)
                        {
                            nbytes = i;
                            rv = apr_socket_send(sock, buffer + o, &nbytes);
                            if (rv != APR_SUCCESS)
                                break;
                            o += nbytes;
                            i -= nbytes;
                        }
                    }
                    else
                        break;
                }
                else if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP)) {
                    rv = APR_EOF;
                    break;
                }
            }
            else
                break;
        }
        if (rv != APR_SUCCESS) {
            break;
        }
    }

    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
         "proxy: CONNECT: finished with poll() - cleaning up");

    /*
     * Step Five: Clean Up
     *
     * Close the socket and clean up
     */

    apr_socket_close(sock);

    return OK;
}
void LLPluginProcessParent::updatePollset()
{
    if(!sInstancesMutex)
    {
        // No instances have been created yet.  There's no work to do.
        return;
    }

    LLMutexLock lock(sInstancesMutex);

    if(sPollSet)
    {
        LL_DEBUGS("PluginPoll") << "destroying pollset " << sPollSet << LL_ENDL;
        // delete the existing pollset.
        apr_pollset_destroy(sPollSet);
        sPollSet = NULL;
        sPollSetPool.destroy();
    }

    std::list<LLPluginProcessParent*>::iterator iter;
    int count = 0;

    // Count the number of instances that want to be in the pollset
    for(iter = sInstances.begin(); iter != sInstances.end(); iter++)
    {
        (*iter)->mPolledInput = false;
        if((*iter)->mPollFD.client_data)
        {
            // This instance has a socket that needs to be polled.
            ++count;
        }
    }

    if(sUseReadThread && sReadThread && !sReadThread->isQuitting())
    {
        if(!sPollSet && (count > 0))
        {
#ifdef APR_POLLSET_NOCOPY
            // The pollset doesn't exist yet.  Create it now.
            sPollSetPool.create();
            apr_status_t status = apr_pollset_create(&sPollSet, count, sPollSetPool(), APR_POLLSET_NOCOPY);
            if(status != APR_SUCCESS)
            {
#endif // APR_POLLSET_NOCOPY
                LL_WARNS("PluginPoll") << "Couldn't create pollset.  Falling back to non-pollset mode." << LL_ENDL;
                sPollSet = NULL;
                sPollSetPool.destroy();
#ifdef APR_POLLSET_NOCOPY
            }
            else
            {
                LL_DEBUGS("PluginPoll") << "created pollset " << sPollSet << LL_ENDL;

                // Pollset was created, add all instances to it.
                for(iter = sInstances.begin(); iter != sInstances.end(); iter++)
                {
                    if((*iter)->mPollFD.client_data)
                    {
                        status = apr_pollset_add(sPollSet, &((*iter)->mPollFD));
                        if(status == APR_SUCCESS)
                        {
                            (*iter)->mPolledInput = true;
                        }
                        else
                        {
                            LL_WARNS("PluginPoll") << "apr_pollset_add failed with status " << status << LL_ENDL;
                        }
                    }
                }
            }
#endif // APR_POLLSET_NOCOPY
        }
    }
}
Ejemplo n.º 29
0
apr_status_t run_test_server(serv_ctx_t *servctx,
                             apr_short_interval_time_t duration,
                             apr_pool_t *pool)
{
    apr_status_t status;
    apr_pollset_t *pollset;
    apr_int32_t num;
    const apr_pollfd_t *desc;

    /* create a new pollset */
#ifdef BROKEN_WSAPOLL
    status = apr_pollset_create_ex(&pollset, 32, pool, 0,
                                 APR_POLLSET_SELECT);
#else
    status = apr_pollset_create(&pollset, 32, pool, 0);
#endif

    if (status != APR_SUCCESS)
        return status;

    /* Don't accept new connection while processing client connection. At
       least for present time.*/
    if (servctx->client_sock) {
        apr_pollfd_t pfd = { 0 };

        pfd.desc_type = APR_POLL_SOCKET;
        pfd.desc.s = servctx->client_sock;
        pfd.reqevents = APR_POLLIN | APR_POLLOUT;

        status = apr_pollset_add(pollset, &pfd);
        if (status != APR_SUCCESS)
            goto cleanup;

        if (servctx->proxy_client_sock) {
            apr_pollfd_t pfd = { 0 };

            pfd.desc_type = APR_POLL_SOCKET;
            pfd.desc.s = servctx->proxy_client_sock;
            pfd.reqevents = APR_POLLIN | APR_POLLOUT;

            status = apr_pollset_add(pollset, &pfd);
            if (status != APR_SUCCESS)
                goto cleanup;
        }
    }
    else {
        apr_pollfd_t pfd = { 0 };

        pfd.desc_type = APR_POLL_SOCKET;
        pfd.desc.s = servctx->serv_sock;
        pfd.reqevents = APR_POLLIN;

        status = apr_pollset_add(pollset, &pfd);
        if (status != APR_SUCCESS)
            goto cleanup;
    }

    status = apr_pollset_poll(pollset, APR_USEC_PER_SEC >> 1, &num, &desc);
    if (status != APR_SUCCESS)
        goto cleanup;

    while (num--) {
        if (desc->desc.s == servctx->serv_sock) {
            status = apr_socket_accept(&servctx->client_sock, servctx->serv_sock,
                                       servctx->pool);
            if (status != APR_SUCCESS)
                goto cleanup;

            serf__log_skt(TEST_VERBOSE, __FILE__, servctx->client_sock,
                          "server/proxy accepted incoming connection.\n");


            apr_socket_opt_set(servctx->client_sock, APR_SO_NONBLOCK, 1);
            apr_socket_timeout_set(servctx->client_sock, 0);

            status = APR_SUCCESS;
            goto cleanup;
        }

        if (desc->desc.s == servctx->client_sock) {
            if (servctx->handshake) {
                status = servctx->handshake(servctx);
                if (status)
                    goto cleanup;
            }

            /* Replay data to socket. */
            status = replay(servctx, desc->rtnevents, pool);

            if (APR_STATUS_IS_EOF(status)) {
                apr_socket_close(servctx->client_sock);
                servctx->client_sock = NULL;
                if (servctx->reset)
                    servctx->reset(servctx);

                /* If this is a proxy and the client closed the connection, also
                   close the connection to the server. */
                if (servctx->proxy_client_sock) {
                    apr_socket_close(servctx->proxy_client_sock);
                    servctx->proxy_client_sock = NULL;
                    goto cleanup;
                }
            }
            else if (APR_STATUS_IS_EAGAIN(status)) {
                status = APR_SUCCESS;
            }
            else if (status != APR_SUCCESS) {
                /* Real error. */
                goto cleanup;
            }
        }
        if (desc->desc.s == servctx->proxy_client_sock) {
            /* Replay data to proxy socket. */
            status = proxy_replay(servctx, desc->rtnevents, pool);
            if (APR_STATUS_IS_EOF(status)) {
                apr_socket_close(servctx->proxy_client_sock);
                servctx->proxy_client_sock = NULL;
            }
            else if (APR_STATUS_IS_EAGAIN(status)) {
                status = APR_SUCCESS;
            }
            else if (status != APR_SUCCESS) {
                /* Real error. */
                goto cleanup;
            }
        }

        desc++;
    }

cleanup:
    apr_pollset_destroy(pollset);

    return status;
}
//static void child_main(int child_num_arg)
void body()
{

    mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
                                   * child initializes
                                   */

    my_child_num = child_num_arg;
    ap_my_pid = getpid();
    requests_this_child = 0;

    ap_fatal_signal_child_setup(ap_server_conf);

    /* Get a sub context for global allocations in this child, so that
     * we can have cleanups occur when the child exits.
     */
    apr_allocator_create(allocator); //// removed deref
    apr_allocator_max_free_set(allocator, ap_max_mem_free);
    apr_pool_create_ex(pchild, pconf, NULL, allocator); //// removed deref
    apr_allocator_owner_set(allocator, pchild);

    apr_pool_create(ptrans, pchild); //// removed deref
    apr_pool_tag(ptrans, 65); // "transaction");

    /* needs to be done before we switch UIDs so we have permissions */
    ap_reopen_scoreboard(pchild, NULL, 0);
    status = apr_proc_mutex_child_init(accept_mutex, ap_lock_fname, pchild); //// removed deref
    if (status != APR_SUCCESS) {
        /* ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf, */
        /*              "Couldnt initialize crossprocess lock in child " */
        /*              "%s %d", ap_lock_fname, ap_accept_lock_mech); */
        clean_child_exit(APEXIT_CHILDFATAL);
    }

    if (unixd_setup_child() > 0) {
        clean_child_exit(APEXIT_CHILDFATAL);
    }

    ap_run_child_init(pchild, ap_server_conf);

    ap_create_sb_handle(sbh, pchild, my_child_num, 0); //// removed deref

    ap_update_child_status(sbh, SERVER_READY, NULL);

    /* Set up the pollfd array */
    /* ### check the status */
    (void) apr_pollset_create(pollset, num_listensocks, pchild, 0); //// removed deref

    num_listensocks = nondet(); assume(num_listensocks>0);

    lr = ap_listeners;
    i = num_listensocks; 
    while (1) {
      if ( i<=0 ) break; 
        int pfd = 0;

        pfd_desc_type = APR_POLL_SOCKET;
        pfd_desc_s = 1; // lr->sd;
        pfd_reqevents = APR_POLLIN;
        pfd_client_data = lr;

        /* ### check the status */
        (void) apr_pollset_add(pollset, pfd); //// removed deref
	i--;
    }

    mpm_state = AP_MPMQ_RUNNING;

    bucket_alloc = apr_bucket_alloc_create(pchild);

    while(1>0) {
      if (die_now>0) break;
        conn_rec *current_conn;
        void *csd;

        /*
         * (Re)initialize this child to a pre-connection state.
         */

        apr_pool_clear(ptrans);

        if ((ap_max_requests_per_child > 0
             && requests_this_child++ >= ap_max_requests_per_child)) {
            clean_child_exit(0);
        }

        (void) ap_update_child_status(sbh, SERVER_READY, NULL);

        /*
         * Wait for an acceptable connection to arrive.
         */

        /* Lock around "accept", if necessary */
        SAFE_ACCEPT(accept_mutex_on());
	do_ACCEPT=1; do_ACCEPT=0;

	dummy = nondet();
	if(dummy > 0) {
          /* goto loc_return; */
          while(1>0) { int ddd; ddd=ddd; }
        }

        if (num_listensocks == 1) {
            /* There is only one listener record, so refer to that one. */
            lr = ap_listeners;
        }
        else {
            /* multiple listening sockets - need to poll */
	  while(1) {
	      int numdesc;
                const void *pdesc;

                /* timeout == -1 == wait forever */
                status = apr_pollset_poll(pollset, -1, numdesc, pdesc); //// removed deref
                if (status != APR_SUCCESS) {
                    if (APR_STATUS_IS_EINTR(status) > 0) {
                        if (one_process>0 && shutdown_pending>0) {
			  /* goto loc_return; */
                          while(1>0) { int ddd; ddd=ddd; }
                        }
                        goto loc_continueA;
                    }
                    /* Single Unix documents select as returning errnos
                     * EBADF, EINTR, and EINVAL... and in none of those
                     * cases does it make sense to continue.  In fact
                     * on Linux 2.0.x we seem to end up with EFAULT
                     * occasionally, and we'd loop forever due to it.
                     */
                    /* ap_log_error5(APLOG_MARK, APLOG_ERR, status, */
                    /*              ap_server_conf, "apr_pollset_poll: (listen)"); */
                    clean_child_exit(1);
                }

                /* We can always use pdesc[0], but sockets at position N
                 * could end up completely starved of attention in a very
                 * busy server. Therefore, we round-robin across the
                 * returned set of descriptors. While it is possible that
                 * the returned set of descriptors might flip around and
                 * continue to starve some sockets, we happen to know the
                 * internal pollset implementation retains ordering
                 * stability of the sockets. Thus, the round-robin should
                 * ensure that a socket will eventually be serviced.
                 */
                if (last_poll_idx >= numdesc)
                    last_poll_idx = 0;

                /* Grab a listener record from the client_data of the poll
                 * descriptor, and advance our saved index to round-robin
                 * the next fetch.
                 *
                 * ### hmm... this descriptor might have POLLERR rather
                 * ### than POLLIN
                 */
                lr = 1; //pdesc[last_poll_idx++].client_data;
		break;

	    loc_continueA: {int yyy2; yyy2=yyy2; }
            }
        }
        /* if we accept() something we don't want to die, so we have to
         * defer the exit
         */
        status = nondet(); // lr->accept_func(&csd, lr, ptrans);

        SAFE_ACCEPT(accept_mutex_off());      /* unlock after "accept" */

        if (status == APR_EGENERAL) {
            /* resource shortage or should-not-occur occured */
            clean_child_exit(1);
        }
        else if (status != APR_SUCCESS) {
	  goto loc_continueB;
        }

        /*
         * We now have a connection, so set it up with the appropriate
         * socket options, file descriptors, and read/write buffers.
         */

        current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_child_num, sbh, bucket_alloc);
        if (current_conn > 0) {
            ap_process_connection(current_conn, csd);
            ap_lingering_close(current_conn);
        }

        /* Check the pod and the generation number after processing a
         * connection so that we'll go away if a graceful restart occurred
         * while we were processing the connection or we are the lucky
         * idle server process that gets to die.
         */
	dummy = nondet();
        if (ap_mpm_pod_check(pod) == APR_SUCCESS) { /* selected as idle? */
            die_now = 1;
        }
        else if (ap_my_generation != dummy) {
	  //ap_scoreboard_image->global->running_generation) { /* restart? */
            /* yeah, this could be non-graceful restart, in which case the
             * parent will kill us soon enough, but why bother checking?
             */
            die_now = 1;
        }
    loc_continueB: { int uuu; uuu=uuu; }
    }
    clean_child_exit(0);
 /* loc_return: */
    while(1>0) { int ddd; ddd=ddd; }
}