static int eloop_sock_table_add_sock(struct eloop_sock_table *table, int sock, eloop_sock_handler handler, void *eloop_data, void *user_data) { struct eloop_sock *tmp; if (table == NULL) return -1; eloop_trace_sock_remove_ref(table); tmp = (struct eloop_sock *) os_realloc(table->table, (table->count + 1) * sizeof(struct eloop_sock)); if (tmp == NULL) return -1; tmp[table->count].sock = sock; tmp[table->count].eloop_data = eloop_data; tmp[table->count].user_data = user_data; tmp[table->count].handler = handler; wpa_trace_record(&tmp[table->count]); table->count++; table->table = tmp; if (sock > eloop.max_sock) eloop.max_sock = sock; table->changed = 1; eloop_trace_sock_add_ref(table); return 0; }
static int eloop_sock_table_add_sock(struct eloop_sock_table *table, int sock, eloop_sock_handler handler, void *eloop_data, void *user_data) { struct eloop_sock *tmp; int new_max_sock; if (sock > eloop.max_sock) new_max_sock = sock; else new_max_sock = eloop.max_sock; if (table == NULL) return -1; #ifdef CONFIG_ELOOP_POLL if (new_max_sock >= eloop.max_pollfd_map) { struct pollfd **nmap; nmap = os_realloc_array(eloop.pollfds_map, new_max_sock + 50, sizeof(struct pollfd *)); if (nmap == NULL) return -1; eloop.max_pollfd_map = new_max_sock + 50; eloop.pollfds_map = nmap; } if (eloop.count + 1 > eloop.max_poll_fds) { struct pollfd *n; int nmax = eloop.count + 1 + 50; n = os_realloc_array(eloop.pollfds, nmax, sizeof(struct pollfd)); if (n == NULL) return -1; eloop.max_poll_fds = nmax; eloop.pollfds = n; } #endif /* CONFIG_ELOOP_POLL */ eloop_trace_sock_remove_ref(table); tmp = os_realloc_array(table->table, table->count + 1, sizeof(struct eloop_sock)); if (tmp == NULL) return -1; tmp[table->count].sock = sock; tmp[table->count].eloop_data = eloop_data; tmp[table->count].user_data = user_data; tmp[table->count].handler = handler; wpa_trace_record(&tmp[table->count]); table->count++; table->table = tmp; eloop.max_sock = new_max_sock; eloop.count++; table->changed = 1; eloop_trace_sock_add_ref(table); return 0; }
void wpa_trace_add_ref_func(struct wpa_trace_ref *ref, const void *addr) { if (addr == NULL) return; ref->addr = addr; wpa_trace_record(ref); dl_list_add(&active_references, &ref->list); }
void wpa_trace_show(const char *title) { struct info { WPA_TRACE_INFO } info; wpa_trace_record(&info); wpa_trace_dump(title, &info); }
void * os_malloc(size_t size) { struct os_alloc_trace *a; a = malloc(sizeof(*a) + size); if (a == NULL) return NULL; a->magic = ALLOC_MAGIC; dl_list_add(&alloc_list, &a->list); a->len = size; wpa_trace_record(a); return a + 1; }
int eloop_register_timeout(unsigned int secs, unsigned int usecs, eloop_timeout_handler handler, void *eloop_data, void *user_data) { struct eloop_timeout *timeout, *tmp; os_time_t now_sec; timeout = os_zalloc(sizeof(*timeout)); if (timeout == NULL) return -1; if (os_get_reltime(&timeout->time) < 0) { os_free(timeout); return -1; } now_sec = timeout->time.sec; timeout->time.sec += secs; if (timeout->time.sec < now_sec) { /* * Integer overflow - assume long enough timeout to be assumed * to be infinite, i.e., the timeout would never happen. */ wpa_printf(MSG_DEBUG, "ELOOP: Too long timeout (secs=%u) to " "ever happen - ignore it", secs); os_free(timeout); return 0; } timeout->time.usec += usecs; while (timeout->time.usec >= 1000000) { timeout->time.sec++; timeout->time.usec -= 1000000; } timeout->eloop_data = eloop_data; timeout->user_data = user_data; timeout->handler = handler; wpa_trace_add_ref(timeout, eloop, eloop_data); wpa_trace_add_ref(timeout, user, user_data); wpa_trace_record(timeout); /* Maintain timeouts in order of increasing time */ dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { if (os_reltime_before(&timeout->time, &tmp->time)) { dl_list_add(tmp->list.prev, &timeout->list); return 0; } } dl_list_add_tail(&eloop.timeout, &timeout->list); return 0; }
int eloop_register_timeout(unsigned int secs, unsigned int usecs, eloop_timeout_handler handler, void *eloop_data, void *user_data) { struct eloop_timeout *timeout, *tmp; timeout = os_zalloc(sizeof(*timeout)); if (timeout == NULL) return -1; if (os_get_time(&timeout->time) < 0) { os_free(timeout); return -1; } timeout->time.sec += secs; timeout->time.usec += usecs; while (timeout->time.usec >= 1000000) { timeout->time.sec++; timeout->time.usec -= 1000000; } timeout->eloop_data = eloop_data; timeout->user_data = user_data; timeout->handler = handler; wpa_trace_add_ref(timeout, eloop, eloop_data); wpa_trace_add_ref(timeout, user, user_data); wpa_trace_record(timeout); /* Maintain timeouts in order of increasing time */ dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { if (os_time_before(&timeout->time, &tmp->time)) { dl_list_add(tmp->list.prev, &timeout->list); return 0; } } dl_list_add_tail(&eloop.timeout, &timeout->list); return 0; }
static int eloop_sock_table_add_sock(struct eloop_sock_table *table, int sock, eloop_sock_handler handler, void *eloop_data, void *user_data) { #ifdef CONFIG_ELOOP_EPOLL struct eloop_sock *temp_table; struct epoll_event ev, *temp_events; int next; #endif /* CONFIG_ELOOP_EPOLL */ struct eloop_sock *tmp; int new_max_sock; if (sock > eloop.max_sock) new_max_sock = sock; else new_max_sock = eloop.max_sock; if (table == NULL) return -1; #ifdef CONFIG_ELOOP_POLL if (new_max_sock >= eloop.max_pollfd_map) { struct pollfd **nmap; nmap = os_realloc_array(eloop.pollfds_map, new_max_sock + 50, sizeof(struct pollfd *)); if (nmap == NULL) return -1; eloop.max_pollfd_map = new_max_sock + 50; eloop.pollfds_map = nmap; } if (eloop.count + 1 > eloop.max_poll_fds) { struct pollfd *n; int nmax = eloop.count + 1 + 50; n = os_realloc_array(eloop.pollfds, nmax, sizeof(struct pollfd)); if (n == NULL) return -1; eloop.max_poll_fds = nmax; eloop.pollfds = n; } #endif /* CONFIG_ELOOP_POLL */ #ifdef CONFIG_ELOOP_EPOLL if (new_max_sock >= eloop.epoll_max_fd) { next = eloop.epoll_max_fd == 0 ? 16 : eloop.epoll_max_fd * 2; temp_table = os_realloc_array(eloop.epoll_table, next, sizeof(struct eloop_sock)); if (temp_table == NULL) return -1; eloop.epoll_max_fd = next; eloop.epoll_table = temp_table; } if (eloop.count + 1 > eloop.epoll_max_event_num) { next = eloop.epoll_max_event_num == 0 ? 8 : eloop.epoll_max_event_num * 2; temp_events = os_realloc_array(eloop.epoll_events, next, sizeof(struct epoll_event)); if (temp_events == NULL) { wpa_printf(MSG_ERROR, "%s: malloc for epoll failed. " "%s\n", __func__, strerror(errno)); return -1; } eloop.epoll_max_event_num = next; eloop.epoll_events = temp_events; } #endif /* CONFIG_ELOOP_EPOLL */ eloop_trace_sock_remove_ref(table); tmp = os_realloc_array(table->table, table->count + 1, sizeof(struct eloop_sock)); if (tmp == NULL) { eloop_trace_sock_add_ref(table); return -1; } tmp[table->count].sock = sock; tmp[table->count].eloop_data = eloop_data; tmp[table->count].user_data = user_data; tmp[table->count].handler = handler; wpa_trace_record(&tmp[table->count]); table->count++; table->table = tmp; eloop.max_sock = new_max_sock; eloop.count++; #ifndef CONFIG_ELOOP_EPOLL table->changed = 1; #endif /* CONFIG_ELOOP_EPOLL */ eloop_trace_sock_add_ref(table); #ifdef CONFIG_ELOOP_EPOLL os_memset(&ev, 0, sizeof(ev)); switch (table->type) { case EVENT_TYPE_READ: ev.events = EPOLLIN; break; case EVENT_TYPE_WRITE: ev.events = EPOLLOUT; break; /* * Exceptions are always checked when using epoll, but I suppose it's * possible that someone registered a socket *only* for exception * handling. */ case EVENT_TYPE_EXCEPTION: ev.events = EPOLLERR | EPOLLHUP; break; } ev.data.fd = sock; if (epoll_ctl(eloop.epollfd, EPOLL_CTL_ADD, sock, &ev) < 0) { wpa_printf(MSG_ERROR, "%s: epoll_ctl(ADD) for fd=%d " "failed. %s\n", __func__, sock, strerror(errno)); return -1; } os_memcpy(&eloop.epoll_table[sock], &table->table[table->count - 1], sizeof(struct eloop_sock)); #endif /* CONFIG_ELOOP_EPOLL */ return 0; }