Пример #1
0
/*
 * look for the node with the given name.  if not exist,
 * create a new one and append to the node list.
 */
static struct makenode *add_target(const char *name)
{
	struct makenode *__restrict node;
	struct makenode *prev, *t;

	node = lookup_target(name);
	if (node)
		return node;
	if (posix_memalign((void*)&node, sizeof(void*), alignof(struct makenode)+strsize(name)) < 0) {
		fprintf(stderr, "Can't malloc: %s\n", strerror(errno));
		exit(1);
	}
	memset(node, 0, alignof(struct makenode)+strsize(name));
	node->name = ((char*)node)+alignof(struct makenode);
	strcpy(node->name, name);

	/* append to the list in alphabetical order */
	prev = NULL;
	for (t = tree_list; t; prev = t, t = t->next)
		if (strcmp(node->name, t->name) < 0)
			break;
	if (prev)
		prev->next = node;
	else
		tree_list = node;
	node->next = t;
	tree_entries++;
	return node;
}
Пример #2
0
/*
 * mark the selected service as an interactive task
 * that should run solely
 */
static void mark_interactive(const char *name)
{
	struct makenode *node = lookup_target(name);
	if (node)
		node->interactive = 1;
}
Пример #3
0
static void filter_files(const char *dir, int prefix, int inverse)
{
	char path[64];
	int i, ndirs;
	static struct dirent **dirlist;
	struct makenode *t, *next;

	filter_prefix = prefix;
#ifdef SUSE	/* SuSE */
	snprintf(path, sizeof(path), "/etc/init.d/%s.d", dir);
#else		/* Debian */
	snprintf(path, sizeof(path), "/etc/%s.d", dir);
#endif
#if defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) >= 600
	if ((i = open(path, o_flags|O_DIRECTORY|O_LARGEFILE)) >= 0) {
		(void)posix_fadvise(i, 0, 0, POSIX_FADV_SEQUENTIAL);
		(void)posix_fadvise(i, 0, 0, POSIX_FADV_NOREUSE);
	}
#endif
	ndirs = scandir(path, &dirlist, dirfilter, alphasort);
#if defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) >= 600
	if (i >= 0) {
		(void)posix_fadvise(i, 0, 0, POSIX_FADV_DONTNEED);
		close(i);
	}
#endif
	/* mark all matching nodes */
	if (ndirs >= 0) {
		for (i = 0; i < ndirs; i++) {
			t = lookup_target(dirlist[i]->d_name + 3);
			if (t) {
				t->status = 1;
				t->filter_prefix = filter_prefix;
				if (asprintf(&t->arg0, "%s/%s", path, dirlist[i]->d_name) < 0)
					t->arg0 = (char*)0;
			}
			free(dirlist[i]);
		}
		free(dirlist);
	}
	/* deselect non-matching nodes */
	for (t = tree_list; t; t = next) {
		next = t->next;
		if ((! t->status && ! inverse) || (t->status && inverse)) {
			/* remove from the list */
			struct makelist *x, *nx;
			struct makenode *p;
			for (x = t->select; x; x = nx) {
				nx = x->next;
				x->node->num_deps--;
				free(x);
			}
			for (x = t->depend; x; x = nx) {
				nx = x->next;
				x->node->num_sels--;
				free(x);
			}
			if (t == tree_list)
				tree_list = next;
			else {
				for (p = tree_list; p->next != t; p = p->next)
					;
				p->next = next;
			}
			/* don't free the node instance itself - it may be selected
			 * by others
			 */
			tree_entries--;
			continue;
		}
		t->status = 0;
	}
}
Пример #4
0
void h2o_socketpool_connect(h2o_socketpool_connect_request_t **_req, h2o_socketpool_t *pool, h2o_url_t *url, h2o_loop_t *loop,
                            h2o_multithread_receiver_t *getaddr_receiver, h2o_socketpool_connect_cb cb, void *data)
{
    struct pool_entry_t *entry = NULL;
    struct on_close_data_t *close_data;

    if (_req != NULL)
        *_req = NULL;

    size_t target = SIZE_MAX;
    h2o_linklist_t *sockets = NULL;

    /* fetch an entry and return it */
    pthread_mutex_lock(&pool->_shared.mutex);
    destroy_expired(pool);

    /* TODO lookup outside this critical section */
    if (is_global_pool(pool)) {
        target = lookup_target(pool, url);
        if (target == SIZE_MAX) {
            h2o_vector_reserve(NULL, &pool->targets, pool->targets.size + 1);
            pool->targets.entries[pool->targets.size++] = h2o_socketpool_create_target(url, NULL);
            target = pool->targets.size - 1;
        }
        sockets = &pool->targets.entries[target]->_shared.sockets;
    } else {
        sockets = &pool->_shared.sockets;
    }
    assert(pool->targets.size != 0);

    while (!h2o_linklist_is_empty(sockets)) {
        if (is_global_pool(pool)) {
            entry = H2O_STRUCT_FROM_MEMBER(struct pool_entry_t, target_link, sockets->next);
        } else {
            entry = H2O_STRUCT_FROM_MEMBER(struct pool_entry_t, all_link, sockets->next);
        }
        h2o_linklist_unlink(&entry->all_link);
        h2o_linklist_unlink(&entry->target_link);
        pthread_mutex_unlock(&pool->_shared.mutex);

        /* test if the connection is still alive */
        char buf[1];
        ssize_t rret = recv(entry->sockinfo.fd, buf, 1, MSG_PEEK);
        if (rret == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
            /* yes! return it */
            size_t entry_target = entry->target;
            h2o_socket_t *sock = h2o_socket_import(loop, &entry->sockinfo);
            free(entry);
            close_data = h2o_mem_alloc(sizeof(*close_data));
            close_data->pool = pool;
            close_data->target = entry_target;
            sock->on_close.cb = on_close;
            sock->on_close.data = close_data;
            cb(sock, NULL, data, &pool->targets.entries[entry_target]->url);
            return;
        }

        /* connection is dead, report, close, and retry */
        if (rret <= 0) {
            static long counter = 0;
            if (__sync_fetch_and_add(&counter, 1) == 0)
                fprintf(stderr, "[WARN] detected close by upstream before the expected timeout (see issue #679)\n");
        } else {
            static long counter = 0;
            if (__sync_fetch_and_add(&counter, 1) == 0)
                fprintf(stderr, "[WARN] unexpectedly received data to a pooled socket (see issue #679)\n");
        }
        destroy_detached(entry);
        pthread_mutex_lock(&pool->_shared.mutex);
    }