示例#1
0
APR_DECLARE(apr_status_t) apr_thread_cond_create(apr_thread_cond_t **cond,
                                                 apr_pool_t *pool)
{
    apr_thread_cond_t *new_cond;
    sem_id rv;
    int i;

    new_cond = (apr_thread_cond_t *)apr_palloc(pool, sizeof(apr_thread_cond_t));

    if (new_cond == NULL)
        return APR_ENOMEM;

    if ((rv = create_sem(1, "apr conditional lock")) < B_OK)
        return rv;
    
    new_cond->lock = rv;
    new_cond->pool = pool;
    APR_RING_INIT(&new_cond->alist, waiter_t, link);
    APR_RING_INIT(&new_cond->flist, waiter_t, link);
        
    for (i=0;i < 10 ;i++) {
        struct waiter_t *nw = make_waiter(pool);
        APR_RING_INSERT_TAIL(&new_cond->flist, nw, waiter_t, link);
    }

    apr_pool_cleanup_register(new_cond->pool,
                              (void *)new_cond, thread_cond_cleanup,
                              apr_pool_cleanup_null);

    *cond = new_cond;
    return APR_SUCCESS;
}
示例#2
0
文件: epoll.c 项目: Ga-vin/apache
static apr_status_t impl_pollset_create(apr_pollset_t *pollset,
                                        apr_uint32_t size,
                                        apr_pool_t *p,
                                        apr_uint32_t flags)
{
    apr_status_t rv;
    int fd;

#ifdef HAVE_EPOLL_CREATE1
    fd = epoll_create1(EPOLL_CLOEXEC);
#else
    fd = epoll_create(size);
#endif
    if (fd < 0) {
        pollset->p = NULL;
        return apr_get_netos_error();
    }

#ifndef HAVE_EPOLL_CREATE1
    {
        int flags;

        if ((flags = fcntl(fd, F_GETFD)) == -1)
            return errno;

        flags |= FD_CLOEXEC;
        if (fcntl(fd, F_SETFD, flags) == -1)
            return errno;
    }
#endif

    pollset->p = apr_palloc(p, sizeof(apr_pollset_private_t));
#if APR_HAS_THREADS
    if ((flags & APR_POLLSET_THREADSAFE) &&
        !(flags & APR_POLLSET_NOCOPY) &&
        ((rv = apr_thread_mutex_create(&pollset->p->ring_lock,
                                       APR_THREAD_MUTEX_DEFAULT,
                                       p)) != APR_SUCCESS)) {
        pollset->p = NULL;
        return rv;
    }
#else
    if (flags & APR_POLLSET_THREADSAFE) {
        pollset->p = NULL;
        return APR_ENOTIMPL;
    }
#endif
    pollset->p->epoll_fd = fd;
    pollset->p->pollset = apr_palloc(p, size * sizeof(struct epoll_event));
    pollset->p->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));

    if (!(flags & APR_POLLSET_NOCOPY)) {
        APR_RING_INIT(&pollset->p->query_ring, pfd_elem_t, link);
        APR_RING_INIT(&pollset->p->free_ring, pfd_elem_t, link);
        APR_RING_INIT(&pollset->p->dead_ring, pfd_elem_t, link);
    }
    return APR_SUCCESS;
}
示例#3
0
APU_DECLARE(apr_status_t) apr_reslist_create(apr_reslist_t **reslist,
                                             int min, int smax, int hmax,
                                             apr_interval_time_t ttl,
                                             apr_reslist_constructor con,
                                             apr_reslist_destructor de,
                                             void *params,
                                             apr_pool_t *pool)
{
    apr_status_t rv;
    apr_reslist_t *rl;

    /* Do some sanity checks so we don't thrash around in the
     * maintenance routine later. */
    if (min > smax || min > hmax || smax > hmax || ttl < 0) {
        return APR_EINVAL;
    }

    rl = apr_pcalloc(pool, sizeof(*rl));
    rl->pool = pool;
    rl->min = min;
    rl->smax = smax;
    rl->hmax = hmax;
    rl->ttl = ttl;
    rl->constructor = con;
    rl->destructor = de;
    rl->params = params;

    APR_RING_INIT(&rl->avail_list, apr_res_t, link);
    APR_RING_INIT(&rl->free_list, apr_res_t, link);

    rv = apr_thread_mutex_create(&rl->listlock, APR_THREAD_MUTEX_DEFAULT,
                                 pool);
    if (rv != APR_SUCCESS) {
        return rv;
    }
    rv = apr_thread_cond_create(&rl->avail, pool);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    rv = reslist_maint(rl);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    apr_pool_cleanup_register(rl->pool, rl, reslist_cleanup,
                              apr_pool_cleanup_null);

    *reslist = rl;

    return APR_SUCCESS;
}
示例#4
0
文件: port.c 项目: Ga-vin/apache
static apr_status_t impl_pollset_create(apr_pollset_t *pollset,
                                             apr_uint32_t size,
                                             apr_pool_t *p,
                                             apr_uint32_t flags)
{
    apr_status_t rv = APR_SUCCESS;
    pollset->p = apr_palloc(p, sizeof(apr_pollset_private_t));
#if APR_HAS_THREADS
    if (flags & APR_POLLSET_THREADSAFE &&
        ((rv = apr_thread_mutex_create(&pollset->p->ring_lock,
                                       APR_THREAD_MUTEX_DEFAULT,
                                       p)) != APR_SUCCESS)) {
        pollset->p = NULL;
        return rv;
    }
#else
    if (flags & APR_POLLSET_THREADSAFE) {
        pollset->p = NULL;
        return APR_ENOTIMPL;
    }
#endif
    pollset->p->waiting = 0;

    pollset->p->port_set = apr_palloc(p, size * sizeof(port_event_t));

    pollset->p->port_fd = port_create();

    if (pollset->p->port_fd < 0) {
        pollset->p = NULL;
        return apr_get_netos_error();
    }

    {
        int flags;

        if ((flags = fcntl(pollset->p->port_fd, F_GETFD)) == -1)
            return errno;

        flags |= FD_CLOEXEC;
        if (fcntl(pollset->p->port_fd, F_SETFD, flags) == -1)
            return errno;
    }

    pollset->p->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));

    APR_RING_INIT(&pollset->p->query_ring, pfd_elem_t, link);
    APR_RING_INIT(&pollset->p->add_ring, pfd_elem_t, link);
    APR_RING_INIT(&pollset->p->free_ring, pfd_elem_t, link);
    APR_RING_INIT(&pollset->p->dead_ring, pfd_elem_t, link);

    return rv;
}
示例#5
0
/** Create timer queue */
APT_DECLARE(apt_timer_queue_t*) apt_timer_queue_create(apr_pool_t *pool)
{
    apt_timer_queue_t *timer_queue = apr_palloc(pool,sizeof(apt_timer_queue_t));
    APR_RING_INIT(&timer_queue->head, apt_timer_t, link);
    timer_queue->elapsed_time = 0;
    return timer_queue;
}
示例#6
0
apt_bool_t mpf_buffer_restart(mpf_buffer_t *buffer)
{
	apr_thread_mutex_lock(buffer->guard);
	APR_RING_INIT(&buffer->head, mpf_chunk_t, link);
	apr_thread_mutex_unlock(buffer->guard);
	return TRUE;
}
示例#7
0
APT_DECLARE(apt_obj_list_t*) apt_list_create(apr_pool_t *pool)
{
	apt_obj_list_t *list = apr_palloc(pool, sizeof(apt_obj_list_t));
	list->pool = pool;
	APR_RING_INIT(&list->head, apt_list_elem_t, link);
	return list;
}
示例#8
0
文件: fdqueue.c 项目: AzerTyQsdF/osx
/**
 * Initialize the fd_queue_t.
 */
apr_status_t ap_queue_init(fd_queue_t * queue, int queue_capacity,
                           apr_pool_t * a)
{
    int i;
    apr_status_t rv;

    if ((rv = apr_thread_mutex_create(&queue->one_big_mutex,
                                      APR_THREAD_MUTEX_DEFAULT,
                                      a)) != APR_SUCCESS) {
        return rv;
    }
    if ((rv = apr_thread_cond_create(&queue->not_empty, a)) != APR_SUCCESS) {
        return rv;
    }

    APR_RING_INIT(&queue->timers, timer_event_t, link);

    queue->data = apr_palloc(a, queue_capacity * sizeof(fd_queue_elem_t));
    queue->bounds = queue_capacity;
    queue->nelts = 0;
    queue->in = 0;
    queue->out = 0;

    /* Set all the sockets in the queue to NULL */
    for (i = 0; i < queue_capacity; ++i)
        queue->data[i].sd = NULL;

    apr_pool_cleanup_register(a, queue, ap_queue_destroy,
                              apr_pool_cleanup_null);

    return APR_SUCCESS;
}
示例#9
0
APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
                                             apr_uint32_t size,
                                             apr_pool_t *p,
                                             apr_uint32_t flags)
{
    apr_status_t rv = APR_SUCCESS;
    *pollset = apr_palloc(p, sizeof(**pollset));
#if APR_HAS_THREADS
    if (flags & APR_POLLSET_THREADSAFE &&
        ((rv = apr_thread_mutex_create(&(*pollset)->ring_lock,
                                       APR_THREAD_MUTEX_DEFAULT,
                                       p) != APR_SUCCESS))) {
        *pollset = NULL;
        return rv;
    }
#else
    if (flags & APR_POLLSET_THREADSAFE) {
        *pollset = NULL;
        return APR_ENOTIMPL;
    }
#endif
    (*pollset)->nelts = 0;
    (*pollset)->nalloc = size;
    (*pollset)->flags = flags;
    (*pollset)->pool = p;

    (*pollset)->port_set = apr_palloc(p, size * sizeof(port_event_t));

    (*pollset)->port_fd = port_create();

    if ((*pollset)->port_fd < 0) {
        return APR_ENOMEM;
    }

    apr_pool_cleanup_register(p, (void *) (*pollset), backend_cleanup,
                              apr_pool_cleanup_null);

    (*pollset)->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));

    APR_RING_INIT(&(*pollset)->query_ring, pfd_elem_t, link);
    APR_RING_INIT(&(*pollset)->add_ring, pfd_elem_t, link);
    APR_RING_INIT(&(*pollset)->free_ring, pfd_elem_t, link);
    APR_RING_INIT(&(*pollset)->dead_ring, pfd_elem_t, link);

    return rv;
}
示例#10
0
/** Create timer manager */
MPF_DECLARE(mpf_timer_manager_t*) mpf_timer_manager_create(mpf_scheduler_t *scheduler, apr_pool_t *pool)
{
    mpf_timer_manager_t *timer_manager = apr_palloc(pool,sizeof(mpf_timer_manager_t));
    APR_RING_INIT(&timer_manager->head, mpf_timer_t, link);
    timer_manager->elapsed_time = 0;
    timer_manager->resolution = 100; /* 100 ms */

    mpf_scheduler_timer_clock_set(scheduler,timer_manager->resolution,mpf_scheduler_proc,timer_manager);
    return timer_manager;
}
示例#11
0
mpf_buffer_t* mpf_buffer_create(apr_pool_t *pool)
{
	mpf_buffer_t *buffer = apr_palloc(pool,sizeof(mpf_buffer_t));
	buffer->pool = pool;
	buffer->cur_chunk = NULL;
	buffer->remaining_chunk_size = 0;
	APR_RING_INIT(&buffer->head, mpf_chunk_t, link);
	apr_thread_mutex_create(&buffer->guard,APR_THREAD_MUTEX_UNNESTED,pool);
	return buffer;
}
示例#12
0
h2_task_queue *h2_tq_create(long id, apr_pool_t *pool)
{
    h2_task_queue *q = apr_pcalloc(pool, sizeof(h2_task_queue));
    if (q) {
        q->id = id;
        APR_RING_ELEM_INIT(q, link);
        APR_RING_INIT(&q->tasks, h2_task, link);
    }
    return q;
}
示例#13
0
kdfilter *kdfilter_new(apr_pool_t *pool) {
    kdfilter *self;
    apr_pool_t *obj_pool;
    const char *name = NULL;
    int spam_enabled, virus_enabled, from_enabled;

    apr_pool_create(&obj_pool, pool);

    self = apr_pcalloc(obj_pool, sizeof(kdfilter));
    APR_RING_INIT(&self->filter_drv_list, filter_driver, link);
    
    /* Register cleanup function. */
    apr_pool_cleanup_register(obj_pool, self, kdfilter_delete, kdfilter_delete);

    /* Add the default filters. */
    do {
        /* Check if we enable the spam filter. */
        spam_enabled = options_get_bool("filter_spam.enabled");
        virus_enabled = options_get_bool("filter_virus.enabled");
        from_enabled = options_get_bool("filter_spam.enabled");

        if (from_enabled && kdfilter_add(self, &filter_from) < 0) {
            name = filter_from.filter_name;
            break;
        }

        if (spam_enabled && kdfilter_add(self, &filter_spam) < 0) {
            name = filter_spam.filter_name;
            break;            
        }

        if (virus_enabled && kdfilter_add(self, &filter_virus) < 0) {
            name = filter_virus.filter_name;
            break;
        }

        if (kdfilter_add(self, &filter_forward) < 0) {
            name = filter_forward.filter_name;
            break;
        }

        self->pool = obj_pool;
        return self;

    } while (0);

    KERROR_PUSH(_filter_, 0, "filter %s failed initialization", name);
    
    apr_pool_destroy(obj_pool);

    return NULL;
}
示例#14
0
APU_DECLARE(apr_bucket_brigade *) apr_brigade_create(apr_pool_t *p,
                                                     apr_bucket_alloc_t *list)
{
    apr_bucket_brigade *b;

    b = apr_palloc(p, sizeof(*b));
    b->p = p;
    b->bucket_alloc = list;

    APR_RING_INIT(&b->list, apr_bucket, link);

    apr_pool_cleanup_register(b->p, b, brigade_cleanup, apr_pool_cleanup_null);
    return b;
}
示例#15
0
/** Create RTSP client */
RTSP_DECLARE(rtsp_client_t*) rtsp_client_create(
									const char *id,
									apr_size_t max_connection_count,
									apr_size_t request_timeout,
									void *obj,
									const rtsp_client_vtable_t *handler,
									apr_pool_t *pool)
{
	apt_task_t *task;
	apt_task_vtable_t *vtable;
	apt_task_msg_pool_t *msg_pool;
	rtsp_client_t *client;

	apt_log(RTSP_LOG_MARK,APT_PRIO_NOTICE,"Create RTSP Client [%s] [%"APR_SIZE_T_FMT"]",
			id, max_connection_count);
	client = apr_palloc(pool,sizeof(rtsp_client_t));
	client->pool = pool;
	client->obj = obj;
	client->vtable = handler;

	msg_pool = apt_task_msg_pool_create_dynamic(sizeof(task_msg_data_t),pool);

	client->task = apt_poller_task_create(
						max_connection_count,
						rtsp_client_poller_signal_process,
						client,
						msg_pool,
						pool);
	if(!client->task) {
		return NULL;
	}

	task = apt_poller_task_base_get(client->task);
	if(task) {
		apt_task_name_set(task,id);
	}

	vtable = apt_poller_task_vtable_get(client->task);
	if(vtable) {
		vtable->process_msg = rtsp_client_task_msg_process;
	}

	APR_RING_INIT(&client->connection_list, rtsp_client_connection_t, link);
	client->request_timeout = (apr_uint32_t)request_timeout;
	return client;
}
示例#16
0
/** Create connection agent. */
MRCP_DECLARE(mrcp_connection_agent_t*) mrcp_client_connection_agent_create(
											const char *id,
											apr_size_t max_connection_count, 
											apt_bool_t offer_new_connection,
											apr_pool_t *pool)
{
	apt_task_t *task;
	apt_task_vtable_t *vtable;
	apt_task_msg_pool_t *msg_pool;
	mrcp_connection_agent_t *agent;

	apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create MRCPv2 Agent [%s] [%"APR_SIZE_T_FMT"]",
				id,	max_connection_count);
	agent = apr_palloc(pool,sizeof(mrcp_connection_agent_t));
	agent->pool = pool;
	agent->request_timeout = 0;
	agent->offer_new_connection = offer_new_connection;
	agent->rx_buffer_size = MRCP_STREAM_BUFFER_SIZE;
	agent->tx_buffer_size = MRCP_STREAM_BUFFER_SIZE;

	msg_pool = apt_task_msg_pool_create_dynamic(sizeof(connection_task_msg_t),pool);

	agent->task = apt_poller_task_create(
					max_connection_count,
					mrcp_client_poller_signal_process,
					agent,
					msg_pool,
					pool);
	if(!agent->task) {
		return NULL;
	}

	task = apt_poller_task_base_get(agent->task);
	if(task) {
		apt_task_name_set(task,id);
	}

	vtable = apt_poller_task_vtable_get(agent->task);
	if(vtable) {
		vtable->process_msg = mrcp_client_agent_msg_process;
	}

	APR_RING_INIT(&agent->connection_list, mrcp_connection_t, link);
	return agent;
}
static apr_status_t thread_pool_construct(apr_thread_pool_t * me,
                                          apr_size_t init_threads,
                                          apr_size_t max_threads)
{
    apr_status_t rv;
    int i;

    me->thd_max = max_threads;
    me->idle_max = init_threads;
    me->threshold = init_threads / 2;
    rv = apr_thread_mutex_create(&me->lock, APR_THREAD_MUTEX_NESTED,
                                 me->pool);
    if (APR_SUCCESS != rv) {
        return rv;
    }
    rv = apr_thread_cond_create(&me->cond, me->pool);
    if (APR_SUCCESS != rv) {
        apr_thread_mutex_destroy(me->lock);
        return rv;
    }
    me->tasks = apr_palloc(me->pool, sizeof(*me->tasks));
    if (!me->tasks) {
        goto CATCH_ENOMEM;
    }
    APR_RING_INIT(me->tasks, apr_thread_pool_task, link);
    me->scheduled_tasks = apr_palloc(me->pool, sizeof(*me->scheduled_tasks));
    if (!me->scheduled_tasks) {
        goto CATCH_ENOMEM;
    }
    APR_RING_INIT(me->scheduled_tasks, apr_thread_pool_task, link);
    me->recycled_tasks = apr_palloc(me->pool, sizeof(*me->recycled_tasks));
    if (!me->recycled_tasks) {
        goto CATCH_ENOMEM;
    }
    APR_RING_INIT(me->recycled_tasks, apr_thread_pool_task, link);
    me->busy_thds = apr_palloc(me->pool, sizeof(*me->busy_thds));
    if (!me->busy_thds) {
        goto CATCH_ENOMEM;
    }
    APR_RING_INIT(me->busy_thds, apr_thread_list_elt, link);
    me->idle_thds = apr_palloc(me->pool, sizeof(*me->idle_thds));
    if (!me->idle_thds) {
        goto CATCH_ENOMEM;
    }
    APR_RING_INIT(me->idle_thds, apr_thread_list_elt, link);
    me->recycled_thds = apr_palloc(me->pool, sizeof(*me->recycled_thds));
    if (!me->recycled_thds) {
        goto CATCH_ENOMEM;
    }
    APR_RING_INIT(me->recycled_thds, apr_thread_list_elt, link);
    me->thd_cnt = me->idle_cnt = me->task_cnt = me->scheduled_task_cnt = 0;
    me->tasks_run = me->tasks_high = me->thd_high = me->thd_timed_out = 0;
    me->spawning_cnt = 0;
    me->idle_wait = 0;
    me->terminated = 0;
    for (i = 0; i < TASK_PRIORITY_SEGS; i++) {
        me->task_idx[i] = NULL;
    }
    goto FINAL_EXIT;
  CATCH_ENOMEM:
    rv = APR_ENOMEM;
    apr_thread_mutex_destroy(me->lock);
    apr_thread_cond_destroy(me->cond);
  FINAL_EXIT:
    return rv;
}
示例#18
0
/*
 * main
 */
int main(int argc, const char * const argv[])
{
    apr_off_t max;
    apr_time_t current, repeat, delay, previous;
    apr_status_t status;
    apr_pool_t *pool, *instance;
    apr_getopt_t *o;
    apr_finfo_t info;
    int retries, isdaemon, limit_found, intelligent, dowork;
    char opt;
    const char *arg;
    char *proxypath, *path;

    interrupted = 0;
    repeat = 0;
    isdaemon = 0;
    dryrun = 0;
    limit_found = 0;
    max = 0;
    verbose = 0;
    realclean = 0;
    benice = 0;
    deldirs = 0;
    intelligent = 0;
    previous = 0; /* avoid compiler warning */
    proxypath = NULL;

    if (apr_app_initialize(&argc, &argv, NULL) != APR_SUCCESS) {
        return 1;
    }
    atexit(apr_terminate);

    if (argc) {
        shortname = apr_filepath_name_get(argv[0]);
    }

    if (apr_pool_create(&pool, NULL) != APR_SUCCESS) {
        return 1;
    }
    apr_pool_abort_set(oom, pool);
    apr_file_open_stderr(&errfile, pool);
    apr_signal(SIGINT, setterm);
    apr_signal(SIGTERM, setterm);

    apr_getopt_init(&o, pool, argc, argv);

    while (1) {
        status = apr_getopt(o, "iDnvrtd:l:L:p:", &opt, &arg);
        if (status == APR_EOF) {
            break;
        }
        else if (status != APR_SUCCESS) {
            usage();
        }
        else {
            switch (opt) {
            case 'i':
                if (intelligent) {
                    usage();
                }
                intelligent = 1;
                break;

            case 'D':
                if (dryrun) {
                    usage();
                }
                dryrun = 1;
                break;

            case 'n':
                if (benice) {
                    usage();
                }
                benice = 1;
                break;

            case 't':
                if (deldirs) {
                    usage();
                }
                deldirs = 1;
                break;

            case 'v':
                if (verbose) {
                    usage();
                }
                verbose = 1;
                break;

            case 'r':
                if (realclean) {
                    usage();
                }
                realclean = 1;
                deldirs = 1;
                break;

            case 'd':
                if (isdaemon) {
                    usage();
                }
                isdaemon = 1;
                repeat = apr_atoi64(arg);
                repeat *= SECS_PER_MIN;
                repeat *= APR_USEC_PER_SEC;
                break;

            case 'l':
                if (limit_found) {
                    usage();
                }
                limit_found = 1;

                do {
                    apr_status_t rv;
                    char *end;

                    rv = apr_strtoff(&max, arg, &end, 10);
                    if (rv == APR_SUCCESS) {
                        if ((*end == 'K' || *end == 'k') && !end[1]) {
                            max *= KBYTE;
                        }
                        else if ((*end == 'M' || *end == 'm') && !end[1]) {
                            max *= MBYTE;
                        }
                        else if ((*end == 'G' || *end == 'g') && !end[1]) {
                            max *= GBYTE;
                        }
                        else if (*end &&        /* neither empty nor [Bb] */
                                 ((*end != 'B' && *end != 'b') || end[1])) {
                            rv = APR_EGENERAL;
                        }
                    }
                    if (rv != APR_SUCCESS) {
                        apr_file_printf(errfile, "Invalid limit: %s"
                                                 APR_EOL_STR APR_EOL_STR, arg);
                        usage();
                    }
                } while(0);
                break;

            case 'p':
                if (proxypath) {
                    usage();
                }
                proxypath = apr_pstrdup(pool, arg);
                if (apr_filepath_set(proxypath, pool) != APR_SUCCESS) {
                    usage();
                }
                break;
            } /* switch */
        } /* else */
    } /* while */

    if (o->ind != argc) {
         usage();
    }

    if (isdaemon && (repeat <= 0 || verbose || realclean || dryrun)) {
         usage();
    }

    if (!isdaemon && intelligent) {
         usage();
    }

    if (!proxypath || max <= 0) {
         usage();
    }

    if (apr_filepath_get(&path, 0, pool) != APR_SUCCESS) {
        usage();
    }
    baselen = strlen(path);

#ifndef DEBUG
    if (isdaemon) {
        apr_file_close(errfile);
        apr_proc_detach(APR_PROC_DETACH_DAEMONIZE);
    }
#endif

    do {
        apr_pool_create(&instance, pool);

        now = apr_time_now();
        APR_RING_INIT(&root, _entry, link);
        delcount = 0;
        unsolicited = 0;
        dowork = 0;

        switch (intelligent) {
        case 0:
            dowork = 1;
            break;

        case 1:
            retries = STAT_ATTEMPTS;
            status = APR_SUCCESS;

            do {
                if (status != APR_SUCCESS) {
                    apr_sleep(STAT_DELAY);
                }
                status = apr_stat(&info, path, APR_FINFO_MTIME, instance);
            } while (status != APR_SUCCESS && !interrupted && --retries);

            if (status == APR_SUCCESS) {
                previous = info.mtime;
                intelligent = 2;
            }
            dowork = 1;
            break;

        case 2:
            retries = STAT_ATTEMPTS;
            status = APR_SUCCESS;

            do {
                if (status != APR_SUCCESS) {
                    apr_sleep(STAT_DELAY);
                }
                status = apr_stat(&info, path, APR_FINFO_MTIME, instance);
            } while (status != APR_SUCCESS && !interrupted && --retries);

            if (status == APR_SUCCESS) {
                if (previous != info.mtime) {
                    dowork = 1;
                }
                previous = info.mtime;
                break;
            }
            intelligent = 1;
            dowork = 1;
            break;
        }

        if (dowork && !interrupted) {
            if (!process_dir(path, instance) && !interrupted) {
                purge(path, instance, max);
            }
            else if (!isdaemon && !interrupted) {
                apr_file_printf(errfile, "An error occurred, cache cleaning "
                                         "aborted." APR_EOL_STR);
                return 1;
            }

            if (intelligent && !interrupted) {
                retries = STAT_ATTEMPTS;
                status = APR_SUCCESS;
                do {
                    if (status != APR_SUCCESS) {
                        apr_sleep(STAT_DELAY);
                    }
                    status = apr_stat(&info, path, APR_FINFO_MTIME, instance);
                } while (status != APR_SUCCESS && !interrupted && --retries);

                if (status == APR_SUCCESS) {
                    previous = info.mtime;
                    intelligent = 2;
                }
                else {
                    intelligent = 1;
                }
            }
        }

        apr_pool_destroy(instance);

        current = apr_time_now();
        if (current < now) {
            delay = repeat;
        }
        else if (current - now >= repeat) {
            delay = repeat;
        }
        else {
            delay = now + repeat - current;
        }

        /* we can't sleep the whole delay time here apiece as this is racy
         * with respect to interrupt delivery - think about what happens
         * if we have tested for an interrupt, then get scheduled
         * before the apr_sleep() call and while waiting for the cpu
         * we do get an interrupt
         */
        if (isdaemon) {
            while (delay && !interrupted) {
                if (delay > APR_USEC_PER_SEC) {
                    apr_sleep(APR_USEC_PER_SEC);
                    delay -= APR_USEC_PER_SEC;
                }
                else {
                    apr_sleep(delay);
                    delay = 0;
                }
            }
        }
    } while (isdaemon && !interrupted);

    if (!isdaemon && interrupted) {
        apr_file_printf(errfile, "Cache cleaning aborted due to user "
                                 "request." APR_EOL_STR);
        return 1;
    }

    return 0;
}
示例#19
0
/*
 * walk the cache directory tree
 */
static int process_dir(char *path, apr_pool_t *pool)
{
    apr_dir_t *dir;
    apr_pool_t *p;
    apr_hash_t *h;
    apr_hash_index_t *i;
    apr_file_t *fd;
    apr_status_t status;
    apr_finfo_t info;
    apr_size_t len;
    apr_time_t current, deviation;
    char *nextpath, *base, *ext, *orig_basename;
    APR_RING_ENTRY(_direntry) anchor;
    DIRENTRY *d, *t, *n;
    ENTRY *e;
    int skip, retries;
    disk_cache_info_t disk_info;

    APR_RING_INIT(&anchor, _direntry, link);
    apr_pool_create(&p, pool);
    h = apr_hash_make(p);
    fd = NULL;
    skip = 0;
    deviation = MAXDEVIATION * APR_USEC_PER_SEC;

    if (apr_dir_open(&dir, path, p) != APR_SUCCESS) {
        return 1;
    }

    while (apr_dir_read(&info, 0, dir) == APR_SUCCESS && !interrupted) {
        if (!strcmp(info.name, ".") || !strcmp(info.name, "..")) {
            continue;
        }
        d = apr_pcalloc(p, sizeof(DIRENTRY));
        d->basename = apr_pstrcat(p, path, "/", info.name, NULL);
        APR_RING_INSERT_TAIL(&anchor, d, _direntry, link);
    }

    apr_dir_close(dir);

    if (interrupted) {
        return 1;
    }

    skip = baselen + 1;

    for (d = APR_RING_FIRST(&anchor);
         !interrupted && d != APR_RING_SENTINEL(&anchor, _direntry, link);
         d=n) {
        n = APR_RING_NEXT(d, link);
        base = strrchr(d->basename, '/');
        if (!base++) {
            base = d->basename;
        }
        ext = strchr(base, '.');

        /* there may be temporary files which may be gone before
         * processing, always skip these if not in realclean mode
         */
        if (!ext && !realclean) {
            if (!strncasecmp(base, AP_TEMPFILE_BASE, AP_TEMPFILE_BASELEN)
                && strlen(base) == AP_TEMPFILE_NAMELEN) {
                continue;
            }
        }

        /* this may look strange but apr_stat() may return errno which
         * is system dependent and there may be transient failures,
         * so just blindly retry for a short while
         */
        retries = STAT_ATTEMPTS;
        status = APR_SUCCESS;
        do {
            if (status != APR_SUCCESS) {
                apr_sleep(STAT_DELAY);
            }
            status = apr_stat(&info, d->basename, DIRINFO, p);
        } while (status != APR_SUCCESS && !interrupted && --retries);

        /* what may happen here is that apache did create a file which
         * we did detect but then does delete the file before we can
         * get file information, so if we don't get any file information
         * we will ignore the file in this case
         */
        if (status != APR_SUCCESS) {
            if (!realclean && !interrupted) {
                continue;
            }
            return 1;
        }

        if (info.filetype == APR_DIR) {
            /* Make a copy of the basename, as process_dir modifies it */
            orig_basename = apr_pstrdup(pool, d->basename);
            if (process_dir(d->basename, pool)) {
                return 1;
            }

            /* If asked to delete dirs, do so now. We don't care if it fails.
             * If it fails, it likely means there was something else there.
             */
            if (deldirs && !dryrun) {
                apr_dir_remove(orig_basename, pool);
            }
            continue;
        }

        if (info.filetype != APR_REG) {
            continue;
        }

        if (!ext) {
            if (!strncasecmp(base, AP_TEMPFILE_BASE, AP_TEMPFILE_BASELEN)
                && strlen(base) == AP_TEMPFILE_NAMELEN) {
                d->basename += skip;
                d->type = TEMP;
                d->dsize = info.size;
                apr_hash_set(h, d->basename, APR_HASH_KEY_STRING, d);
            }
            continue;
        }

        if (!strcasecmp(ext, CACHE_HEADER_SUFFIX)) {
            *ext = '\0';
            d->basename += skip;
            /* if a user manually creates a '.header' file */
            if (d->basename[0] == '\0') {
                continue;
            }
            t = apr_hash_get(h, d->basename, APR_HASH_KEY_STRING);
            if (t) {
                d = t;
            }
            d->type |= HEADER;
            d->htime = info.mtime;
            d->hsize = info.size;
            apr_hash_set(h, d->basename, APR_HASH_KEY_STRING, d);
            continue;
        }

        if (!strcasecmp(ext, CACHE_DATA_SUFFIX)) {
            *ext = '\0';
            d->basename += skip;
            /* if a user manually creates a '.data' file */
            if (d->basename[0] == '\0') {
                continue;
            }
            t = apr_hash_get(h, d->basename, APR_HASH_KEY_STRING);
            if (t) {
                d = t;
            }
            d->type |= DATA;
            d->dtime = info.mtime;
            d->dsize = info.size;
            apr_hash_set(h, d->basename, APR_HASH_KEY_STRING, d);
        }
    }

    if (interrupted) {
        return 1;
    }

    path[baselen] = '\0';

    for (i = apr_hash_first(p, h); i && !interrupted; i = apr_hash_next(i)) {
        void *hvalue;
        apr_uint32_t format;

        apr_hash_this(i, NULL, NULL, &hvalue);
        d = hvalue;

        switch(d->type) {
        case HEADERDATA:
            nextpath = apr_pstrcat(p, path, "/", d->basename,
                                   CACHE_HEADER_SUFFIX, NULL);
            if (apr_file_open(&fd, nextpath, APR_FOPEN_READ | APR_FOPEN_BINARY,
                              APR_OS_DEFAULT, p) == APR_SUCCESS) {
                len = sizeof(format);
                if (apr_file_read_full(fd, &format, len,
                                       &len) == APR_SUCCESS) {
                    if (format == DISK_FORMAT_VERSION) {
                        apr_off_t offset = 0;

                        apr_file_seek(fd, APR_SET, &offset);

                        len = sizeof(disk_cache_info_t);

                        if (apr_file_read_full(fd, &disk_info, len,
                                               &len) == APR_SUCCESS) {
                            apr_file_close(fd);
                            e = apr_palloc(pool, sizeof(ENTRY));
                            APR_RING_INSERT_TAIL(&root, e, _entry, link);
                            e->expire = disk_info.expire;
                            e->response_time = disk_info.response_time;
                            e->htime = d->htime;
                            e->dtime = d->dtime;
                            e->hsize = d->hsize;
                            e->dsize = d->dsize;
                            e->basename = apr_pstrdup(pool, d->basename);
                            break;
                        }
                        else {
                            apr_file_close(fd);
                        }
                    }
                    else if (format == VARY_FORMAT_VERSION) {
                        /* This must be a URL that added Vary headers later,
                         * so kill the orphaned .data file
                         */
                        apr_file_close(fd);
                        apr_file_remove(apr_pstrcat(p, path, "/", d->basename,
                                                    CACHE_DATA_SUFFIX, NULL),
                                        p);
                    }
                }
                else {
                    apr_file_close(fd);
                }

            }
            /* we have a somehow unreadable headers file which is associated
             * with a data file. this may be caused by apache currently
             * rewriting the headers file. thus we may delete the file set
             * either in realclean mode or if the headers file modification
             * timestamp is not within a specified positive or negative offset
             * to the current time.
             */
            current = apr_time_now();
            if (realclean || d->htime < current - deviation
                || d->htime > current + deviation) {
                delete_entry(path, d->basename, p);
                unsolicited += d->hsize;
                unsolicited += d->dsize;
            }
            break;

        /* single data and header files may be deleted either in realclean
         * mode or if their modification timestamp is not within a
         * specified positive or negative offset to the current time.
         * this handling is necessary due to possible race conditions
         * between apache and this process
         */
        case HEADER:
            current = apr_time_now();
            nextpath = apr_pstrcat(p, path, "/", d->basename,
                                   CACHE_HEADER_SUFFIX, NULL);
            if (apr_file_open(&fd, nextpath, APR_FOPEN_READ | APR_FOPEN_BINARY,
                              APR_OS_DEFAULT, p) == APR_SUCCESS) {
                len = sizeof(format);
                if (apr_file_read_full(fd, &format, len,
                                       &len) == APR_SUCCESS) {
                    if (format == VARY_FORMAT_VERSION) {
                        apr_time_t expires;

                        len = sizeof(expires);

                        apr_file_read_full(fd, &expires, len, &len);

                        apr_file_close(fd);

                        if (expires < current) {
                            delete_entry(path, d->basename, p);
                        }
                        break;
                    }
                }
                apr_file_close(fd);
            }

            if (realclean || d->htime < current - deviation
                || d->htime > current + deviation) {
                delete_entry(path, d->basename, p);
                unsolicited += d->hsize;
            }
            break;

        case DATA:
            current = apr_time_now();
            if (realclean || d->dtime < current - deviation
                || d->dtime > current + deviation) {
                delete_entry(path, d->basename, p);
                unsolicited += d->dsize;
            }
            break;

        /* temp files may only be deleted in realclean mode which
         * is asserted above if a tempfile is in the hash array
         */
        case TEMP:
            delete_file(path, d->basename, p);
            unsolicited += d->dsize;
            break;
        }
    }

    if (interrupted) {
        return 1;
    }

    apr_pool_destroy(p);

    if (benice) {
        apr_sleep(NICE_DELAY);
    }

    if (interrupted) {
        return 1;
    }

    return 0;
}
示例#20
0
/**
 * Initialize a bean that has already been allocated with the given
 * BMX Objectname.
 * @param bean The pre-allocated bean object to initialize.
 * @param objectname The BMX Objectname for this new bean.
 */
void bmx_bean_init(struct bmx_bean *bean,
                   struct bmx_objectname *objectname)
{
    bean->objectname = objectname;
    APR_RING_INIT(&(bean->bean_props), bmx_property, link);
}
示例#21
0
/* core's child-status hook
 * tracks number of remaining children per generation and
 * runs the end-generation hook when the last child of
 * a generation exits
 */
void ap_core_child_status(server_rec *s, pid_t pid,
                          ap_generation_t gen, int slot,
                          mpm_child_status status)
{
    mpm_gen_info_t *cur;
    const char *status_msg = "unknown status";

    if (!gen_head_init) { /* where to run this? */
        gen_head_init = 1;
        geninfo = apr_pcalloc(s->process->pool, sizeof *geninfo);
        unused_geninfo = apr_pcalloc(s->process->pool, sizeof *unused_geninfo);
        APR_RING_INIT(geninfo, mpm_gen_info_t, link);
        APR_RING_INIT(unused_geninfo, mpm_gen_info_t, link);
    }

    cur = APR_RING_FIRST(geninfo);
    while (cur != APR_RING_SENTINEL(geninfo, mpm_gen_info_t, link) &&
           cur->gen != gen) {
        cur = APR_RING_NEXT(cur, link);
    }

    switch(status) {
    case MPM_CHILD_STARTED:
        status_msg = "started";
        if (cur == APR_RING_SENTINEL(geninfo, mpm_gen_info_t, link)) {
            /* first child for this generation */
            if (!APR_RING_EMPTY(unused_geninfo, mpm_gen_info_t, link)) {
                cur = APR_RING_FIRST(unused_geninfo);
                APR_RING_REMOVE(cur, link);
                cur->active = cur->done = 0;
            }
            else {
                cur = apr_pcalloc(s->process->pool, sizeof *cur);
            }
            cur->gen = gen;
            APR_RING_ELEM_INIT(cur, link);
            APR_RING_INSERT_HEAD(geninfo, cur, mpm_gen_info_t, link);
        }
        ap_random_parent_after_fork();
        ++cur->active;
        break;
    case MPM_CHILD_EXITED:
        ap_update_global_status();
        status_msg = "exited";
        if (cur == APR_RING_SENTINEL(geninfo, mpm_gen_info_t, link)) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00546)
                         "no record of generation %d of exiting child %" APR_PID_T_FMT,
                         gen, pid);
        }
        else {
            --cur->active;
            if (!cur->active && cur->done) { /* no children, server has stopped/restarted */
                end_gen(cur);
            }
        }
        break;
    case MPM_CHILD_LOST_SLOT:
        status_msg = "lost slot";
        /* we don't track by slot, so it doesn't matter */
        break;
    }
    ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, s,
                 "mpm child %" APR_PID_T_FMT " (gen %d/slot %d) %s",
                 pid, gen, slot, status_msg);
}
示例#22
0
/** Create connection agent */
MRCP_DECLARE(mrcp_connection_agent_t*) mrcp_server_connection_agent_create(
										const char *id,
										const char *listen_ip,
										apr_port_t listen_port,
										apr_size_t max_connection_count,
										apt_bool_t force_new_connection,
										apr_pool_t *pool)
{
	apt_task_t *task;
	apt_task_vtable_t *vtable;
	apt_task_msg_pool_t *msg_pool;
	mrcp_connection_agent_t *agent;

	if(!listen_ip) {
		return NULL;
	}
	
	apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create MRCPv2 Agent [%s] %s:%hu [%"APR_SIZE_T_FMT"]",
		id,listen_ip,listen_port,max_connection_count);
	agent = apr_palloc(pool,sizeof(mrcp_connection_agent_t));
	agent->pool = pool;
	agent->sockaddr = NULL;
	agent->listen_sock = NULL;
	agent->force_new_connection = force_new_connection;
	agent->rx_buffer_size = MRCP_STREAM_BUFFER_SIZE;
	agent->tx_buffer_size = MRCP_STREAM_BUFFER_SIZE;

	apr_sockaddr_info_get(&agent->sockaddr,listen_ip,APR_INET,listen_port,0,pool);
	if(!agent->sockaddr) {
		return NULL;
	}

	msg_pool = apt_task_msg_pool_create_dynamic(sizeof(connection_task_msg_t),pool);
	
	agent->task = apt_poller_task_create(
					max_connection_count + 1,
					mrcp_server_poller_signal_process,
					agent,
					msg_pool,
					pool);
	if(!agent->task) {
		return NULL;
	}

	task = apt_poller_task_base_get(agent->task);
	if(task) {
		apt_task_name_set(task,id);
	}

	vtable = apt_poller_task_vtable_get(agent->task);
	if(vtable) {
		vtable->destroy = mrcp_server_agent_on_destroy;
		vtable->process_msg = mrcp_server_agent_msg_process;
	}

	APR_RING_INIT(&agent->connection_list, mrcp_connection_t, link);
	agent->pending_channel_table = apr_hash_make(pool);

	if(mrcp_server_agent_listening_socket_create(agent) != TRUE) {
		apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Listening Socket [%s] %s:%hu", 
				id,
				listen_ip,
				listen_port);
	}
	return agent;
}
示例#23
0
文件: kqueue.c 项目: Ga-vin/apache
static apr_status_t impl_pollset_create(apr_pollset_t *pollset,
                                        apr_uint32_t size,
                                        apr_pool_t *p,
                                        apr_uint32_t flags)
{
    apr_status_t rv;
    pollset->p = apr_palloc(p, sizeof(apr_pollset_private_t));
#if APR_HAS_THREADS
    if (flags & APR_POLLSET_THREADSAFE &&
        ((rv = apr_thread_mutex_create(&pollset->p->ring_lock,
                                       APR_THREAD_MUTEX_DEFAULT,
                                       p)) != APR_SUCCESS)) {
        pollset->p = NULL;
        return rv;
    }
#else
    if (flags & APR_POLLSET_THREADSAFE) {
        pollset->p = NULL;
        return APR_ENOTIMPL;
    }
#endif

    /* POLLIN and POLLOUT are represented in different returned
     * events, so we need 2 entries per descriptor in the result set,
     * both for what is returned by kevent() and what is returned to
     * the caller of apr_pollset_poll() (since it doesn't spend the
     * CPU to coalesce separate APR_POLLIN and APR_POLLOUT events
     * for the same descriptor)
     */
    pollset->p->setsize = 2 * size;

    pollset->p->ke_set =
        (struct kevent *) apr_palloc(p, pollset->p->setsize * sizeof(struct kevent));

    memset(pollset->p->ke_set, 0, pollset->p->setsize * sizeof(struct kevent));

    pollset->p->kqueue_fd = kqueue();

    if (pollset->p->kqueue_fd == -1) {
        pollset->p = NULL;
        return apr_get_netos_error();
    }

    {
        int flags;

        if ((flags = fcntl(pollset->p->kqueue_fd, F_GETFD)) == -1)
            return errno;

        flags |= FD_CLOEXEC;
        if (fcntl(pollset->p->kqueue_fd, F_SETFD, flags) == -1)
            return errno;
    }

    pollset->p->result_set = apr_palloc(p, pollset->p->setsize * sizeof(apr_pollfd_t));

    APR_RING_INIT(&pollset->p->query_ring, pfd_elem_t, link);
    APR_RING_INIT(&pollset->p->free_ring, pfd_elem_t, link);
    APR_RING_INIT(&pollset->p->dead_ring, pfd_elem_t, link);

    return APR_SUCCESS;
}
示例#24
0
MPF_DECLARE(mpf_context_factory_t*) mpf_context_factory_create(apr_pool_t *pool)
{
	mpf_context_factory_t *factory = apr_palloc(pool, sizeof(mpf_context_factory_t));
	APR_RING_INIT(&factory->head, mpf_context_t, link);
	return factory;
}
示例#25
0
/** Create RTSP server */
RTSP_DECLARE(rtsp_server_t*) rtsp_server_create(
									const char *id,
									const char *listen_ip,
									apr_port_t listen_port,
									apr_size_t max_connection_count,
									void *obj,
									const rtsp_server_vtable_t *handler,
									apr_pool_t *pool)
{
	apt_task_t *task;
	apt_task_vtable_t *vtable;
	apt_task_msg_pool_t *msg_pool;
	rtsp_server_t *server;

	if(!listen_ip) {
		return NULL;
	}

	apt_log(RTSP_LOG_MARK,APT_PRIO_NOTICE,"Create RTSP Server [%s] %s:%hu [%"APR_SIZE_T_FMT"]",
			id,
			listen_ip,
			listen_port,
			max_connection_count);
	server = apr_palloc(pool,sizeof(rtsp_server_t));
	server->pool = pool;
	server->obj = obj;
	server->vtable = handler;

	server->listen_sock = NULL;
	server->sockaddr = NULL;
	apr_sockaddr_info_get(&server->sockaddr,listen_ip,APR_INET,listen_port,0,pool);
	if(!server->sockaddr) {
		return NULL;
	}

	msg_pool = apt_task_msg_pool_create_dynamic(sizeof(task_msg_data_t),pool);

	server->task = apt_poller_task_create(
						max_connection_count + 1,
						rtsp_server_poller_signal_process,
						server,
						msg_pool,
						pool);
	if(!server->task) {
		return NULL;
	}

	task = apt_poller_task_base_get(server->task);
	if(task) {
		apt_task_name_set(task,id);
	}

	vtable = apt_poller_task_vtable_get(server->task);
	if(vtable) {
		vtable->destroy = rtsp_server_on_destroy;
		vtable->process_msg = rtsp_server_task_msg_process;
	}

	APR_RING_INIT(&server->connection_list, rtsp_server_connection_t, link);

	if(rtsp_server_listening_socket_create(server) != TRUE) {
		apt_log(RTSP_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Listening Socket [%s] %s:%hu", 
				id,
				listen_ip,
				listen_port);
	}
	return server;
}