Ejemplo n.º 1
0
static int32_t
my_g_dispatch_add(enum qb_loop_priority p, int32_t fd, int32_t evts,
		  void *data, qb_ipcs_dispatch_fn_t fn)
{
	struct gio_to_qb_poll *adaptor;
	GIOChannel *channel;
	int32_t res = 0;

	res = qb_array_index(gio_map, fd, (void **)&adaptor);
	if (res < 0) {
		return res;
	}
	if (adaptor->is_used) {
		return -EEXIST;
	}

	channel = g_io_channel_unix_new(fd);
	if (!channel) {
		return -ENOMEM;
	}

	adaptor->channel = channel;
	adaptor->fn = fn;
	adaptor->events = evts;
	adaptor->data = data;
	adaptor->p = p;
	adaptor->is_used = TRUE;

	g_io_add_watch(channel, evts, gio_read_socket, adaptor);
	return 0;
}
Ejemplo n.º 2
0
static int32_t
_poll_and_add_to_jobs_(struct qb_loop_source *src, int32_t ms_timeout)
{
	int32_t i;
	int32_t res;
	int32_t new_jobs = 0;
	struct qb_poll_entry *pe;
	struct qb_poll_source *s = (struct qb_poll_source *)src;

	qb_poll_fds_usage_check_(s);

	for (i = 0; i < s->poll_entry_count; i++) {
		assert(qb_array_index(s->poll_entries, i, (void **)&pe) == 0);
		memcpy(&s->ufds[i], &pe->ufd, sizeof(struct pollfd));
	}

retry_poll:
	res = poll(s->ufds, s->poll_entry_count, ms_timeout);
	if (errno == EINTR && res == -1) {
		goto retry_poll;
	} else if (res == -1) {
		return -errno;
	}

	for (i = 0; i < s->poll_entry_count; i++) {
		if (s->ufds[i].fd == -1 || s->ufds[i].revents == 0) {
			/*
			 * empty entry
			 */
			continue;
		}
		assert(qb_array_index(s->poll_entries, i, (void **)&pe) == 0);
		if (pe->state != QB_POLL_ENTRY_ACTIVE ||
		    s->ufds[i].revents == pe->ufd.revents) {
			/*
			 * Wrong state to accept an event.
			 */
			continue;
		}
		pe->ufd.revents = s->ufds[i].revents;
		new_jobs += pe->add_to_jobs(src->l, pe);
	}

	return new_jobs;
}
Ejemplo n.º 3
0
static int32_t
gio_poll_dispatch_add(enum qb_loop_priority p, int32_t fd, int32_t evts,
                      void *data, qb_ipcs_dispatch_fn_t fn)
{
    struct gio_to_qb_poll *adaptor;
    GIOChannel *channel;
    int32_t res = 0;

    res = qb_array_index(gio_map, fd, (void **)&adaptor);
    if (res < 0) {
        crm_err("Array lookup failed for fd=%d: %d", fd, res);
        return res;
    }

    crm_trace("Adding fd=%d to mainloop as adapater %p", fd, adaptor);
    if (adaptor->is_used) {
        crm_err("Adapter for descriptor %d is still in-use", fd);
        return -EEXIST;
    }

    /* channel is created with ref_count = 1 */
    channel = g_io_channel_unix_new(fd);
    if (!channel) {
        crm_err("No memory left to add fd=%d", fd);
        return -ENOMEM;
    }

    /* Because unlike the poll() API, glib doesn't tell us about HUPs by default */
    evts |= (G_IO_HUP | G_IO_NVAL | G_IO_ERR);

    adaptor->fn = fn;
    adaptor->events = evts;
    adaptor->data = data;
    adaptor->p = p;
    adaptor->is_used = QB_TRUE;
    adaptor->source =
        g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, evts, gio_read_socket, adaptor,
                            gio_poll_destroy);

    /* Now that mainloop now holds a reference to channel,
     * thanks to g_io_add_watch_full(), drop ours from g_io_channel_unix_new().
     *
     * This means that channel will be free'd by:
     * g_main_context_dispatch()
     *  -> g_source_destroy_internal()
     *      -> g_source_callback_unref()
     * shortly after gio_poll_destroy() completes
     */
    g_io_channel_unref(channel);

    crm_trace("Added to mainloop with gsource id=%d", adaptor->source);
    if (adaptor->source > 0) {
        return 0;
    }

    return -EINVAL;
}
Ejemplo n.º 4
0
Archivo: bms.c Proyecto: fjrti/libqb
static int32_t my_g_dispatch_del(int32_t fd)
{
	struct gio_to_qb_poll *adaptor;
	if (qb_array_index(gio_map, fd, (void**)&adaptor) == 0) {
		g_io_channel_unref(adaptor->channel);
		adaptor->is_used = FALSE;
	}
	return 0;
}
Ejemplo n.º 5
0
static int32_t
gio_poll_dispatch_del(int32_t fd)
{
    struct gio_to_qb_poll *adaptor;
    crm_trace("Looking for fd=%d", fd);
    if (qb_array_index(gio_map, fd, (void**)&adaptor) == 0) {
        crm_trace("Marking adaptor %p unused (ref=%d)", adaptor, gio_adapter_refcount(adaptor));
        adaptor->is_used = QB_FALSE;
    }
    return 0;
}
Ejemplo n.º 6
0
static int32_t
gio_poll_dispatch_del(int32_t fd)
{
    struct gio_to_qb_poll *adaptor;
    crm_trace("Looking for fd=%d", fd);
    if (qb_array_index(gio_map, fd, (void**)&adaptor) == 0) {
        crm_trace("Marking adaptor %p unused", adaptor);
        g_io_channel_unref(adaptor->channel);
        adaptor->is_used = QB_FALSE;
    }
    return 0;
}
Ejemplo n.º 7
0
static void
_log_register_callsites(qb_array_t * a, uint32_t bin)
{
	struct qb_log_callsite *start;
	struct qb_log_callsite *stop;
	int32_t rc = qb_array_index(callsite_arr,
				    bin * callsite_elems_per_bin,
				    (void **)&start);
	if (rc == 0) {
		stop = &start[callsite_elems_per_bin];
		rc = qb_log_callsites_register(start, stop);
		assert(rc == 0);
	}
}
Ejemplo n.º 8
0
static int32_t
gio_poll_dispatch_del(int32_t fd)
{
    struct gio_to_qb_poll *adaptor;

    crm_trace("Looking for fd=%d", fd);
    if (qb_array_index(gio_map, fd, (void **)&adaptor) == 0) {
        if (adaptor->source) {
            g_source_remove(adaptor->source);
            adaptor->source = 0;
        }
    }
    return 0;
}
Ejemplo n.º 9
0
void
qb_log_dcs_fini(void)
{
	struct callsite_list *csl_head;
	struct callsite_list *csl_next;
	struct callsite_list *csl;
	int32_t i;
	int32_t rc;
	struct qb_log_callsite *cs = NULL;
	int32_t cnt = qb_array_num_bins_get(lookup_arr);
	cnt *= qb_array_elems_per_bin_get(lookup_arr);

	for (i = 0; i < cnt; i++) {
		rc = qb_array_index(lookup_arr, i, (void **)&csl_head);
		if (rc != 0 || csl_head->next == NULL) {
			continue;
		}

		for (csl = csl_head->next; csl; csl = csl_next) {
			csl_next = csl->next;
			free(csl);
		}
	}

	for (i = 0; i < callsite_arr_next; i++) {
		rc = qb_array_index(callsite_arr, i, (void **)&cs);
		if (rc == 0 && cs){
			free((char*)cs->function);
			free((char*)cs->filename);
			free((char*)cs->format);
		}
	}

	qb_array_free(lookup_arr);
	qb_array_free(callsite_arr);
	(void)qb_thread_lock_destroy(arr_next_lock);
}
Ejemplo n.º 10
0
static int32_t
gio_poll_dispatch_del(int32_t fd)
{
    struct gio_to_qb_poll *adaptor;

    crm_trace("Looking for fd=%d", fd);
    if (qb_array_index(gio_map, fd, (void **)&adaptor) == 0) {
        crm_trace("Marking adaptor %p unused", adaptor);
        if (adaptor->source) {
            g_source_remove(adaptor->source);
            adaptor->source = 0;
        }
        adaptor->is_used = QB_FALSE;
    }
    return 0;
}
Ejemplo n.º 11
0
static int32_t
gio_poll_dispatch_add(enum qb_loop_priority p, int32_t fd, int32_t evts,
                  void *data, qb_ipcs_dispatch_fn_t fn)
{
    struct gio_to_qb_poll *adaptor;
    GIOChannel *channel;
    int32_t res = 0;

    res = qb_array_index(gio_map, fd, (void**)&adaptor);
    if (res < 0) {
        crm_err("Array lookup failed for fd=%d: %d", fd, res);
        return res;
    }

    crm_trace("Adding fd=%d to mainloop as adapater %p", fd, adaptor);
    if (adaptor->is_used) {
        crm_err("Adapter for descriptor %d is still in-use", fd);
        return -EEXIST;
    }

    channel = g_io_channel_unix_new(fd);
    if (!channel) {
        crm_err("No memory left to add fd=%d", fd);
        return -ENOMEM;
    }

    /* Because unlike the poll() API, glib doesn't tell us about HUPs by default */
    evts |= (G_IO_HUP|G_IO_NVAL|G_IO_ERR);

    adaptor->channel = channel;
    adaptor->fn = fn;
    adaptor->events = evts;
    adaptor->data = data;
    adaptor->p = p;
    adaptor->is_used = QB_TRUE;

    res = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, evts, gio_read_socket, adaptor, gio_destroy);
    crm_trace("Added to mainloop with gsource id=%d", res);
    if(res > 0) {
        return 0;
    }
    
    return -EINVAL;
}
Ejemplo n.º 12
0
static struct qb_log_callsite *
_log_dcs_new_cs(const char *function,
		const char *filename,
		const char *format,
		uint8_t priority, uint32_t lineno, uint32_t tags)
{
	struct qb_log_callsite *cs;
	int32_t rc = qb_array_index(callsite_arr,
				    callsite_arr_next++,
				    (void **)&cs);
	assert(rc == 0);
	assert(cs != NULL);

	cs->function = strdup(function);
	cs->filename = strdup(filename);
	cs->format = strdup(format);
	cs->priority = priority;
	cs->lineno = lineno;
	cs->tags = tags;

	return cs;
}
Ejemplo n.º 13
0
struct qb_log_callsite *
qb_log_dcs_get(int32_t * newly_created,
	       const char *function,
	       const char *filename,
	       const char *format,
	       uint8_t priority, uint32_t lineno, uint32_t tags)
{
	int32_t rc;
	struct qb_log_callsite *cs = NULL;
	struct callsite_list *csl_head;
	struct callsite_list *csl_last = NULL;
	struct callsite_list *csl;
	const char *safe_filename = filename;
	const char *safe_function = function;
	const char *safe_format = format;

	if (filename == NULL) {
		safe_filename = "";
	}
	if (function == NULL) {
		safe_function = "";
	}
	if (format == NULL) {
		safe_format = "";
	}
	/*
	 * try the fastest access first (no locking needed)
	 */
	rc = qb_array_index(lookup_arr, lineno, (void **)&csl_head);
	assert(rc == 0);
	if (csl_head->cs &&
		priority == csl_head->cs->priority &&
		strcmp(safe_filename, csl_head->cs->filename) == 0 &&
		strcmp(safe_format, csl_head->cs->format) == 0) {
		return csl_head->cs;
	}
	/*
	 * so we will either have to create it or go through a list, so lock it.
	 */
	(void)qb_thread_lock(arr_next_lock);
	if (csl_head->cs == NULL) {
		csl_head->cs = _log_dcs_new_cs(safe_function, safe_filename, safe_format,
					       priority, lineno, tags);
		cs = csl_head->cs;
		csl_head->next = NULL;
		*newly_created = QB_TRUE;
	} else {
		for (csl = csl_head; csl; csl = csl->next) {
			assert(csl->cs->lineno == lineno);
			if (priority == csl->cs->priority &&
			    strcmp(safe_format, csl->cs->format) == 0 &&
			    strcmp(safe_filename, csl->cs->filename) == 0) {
				cs = csl->cs;
				break;
			}
			csl_last = csl;
		}

		if (cs == NULL) {
			csl = calloc(1, sizeof(struct callsite_list));
			if (csl == NULL) {
				goto cleanup;
			}
			csl->cs = _log_dcs_new_cs(safe_function, safe_filename, safe_format,
						  priority, lineno, tags);
			csl->next = NULL;
			csl_last->next = csl;
			cs = csl->cs;
			*newly_created = QB_TRUE;
		}
	}
cleanup:
	(void)qb_thread_unlock(arr_next_lock);

	return cs;
}