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; }
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; }
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; }
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; }
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; }
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; }
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); } }
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; }
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); }
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; }
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; }
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; }
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; }