void route_put( route_t* route ) { bool do_delete; do_delete = false; mutex_lock( route_mutex, LOCK_IGNORE_SIGNAL ); if ( --route->ref_count == 0 ) { array_remove_item( &device_routes, route ); do_delete = true; } mutex_unlock( route_mutex ); if ( do_delete ) { if ( route->device != NULL ) { net_device_put( route->device ); } kfree( route ); } }
int event_loop_run() { int timeout = global_event_loop.min_timer_value; while (1) { int ret = poll(global_event_loop.fds, global_event_loop.fd_entries.size, timeout); if (ret == -1) { msg(MSG_ERROR, "Error occured while polling: %s", strerror(errno)); continue; } if (ret > 0) { // At least one file descriptor is ready for reading size_t i; for (i = 0; i < global_event_loop.fd_entries.size; i++) { struct event_loop_fd_entry *fd_entry = ((struct event_loop_fd_entry *) global_event_loop.fd_entries.buffer) + i; struct pollfd *fd = global_event_loop.fds + i; // DPRINTF("%d", fd->revents); if (fd->revents & POLLIN) (*fd_entry->callback)(fd_entry->fd, fd_entry->user_param); else if (fd->revents & (POLLERR | POLLHUP | POLLNVAL)) { if (fd_entry->error_callback) (*fd_entry->error_callback)(fd_entry->fd, fd_entry->user_param); // Remove from event loop array_remove_item(&global_event_loop.fd_entries, i); // Remove from pollfd list memmove(global_event_loop.fds + i, global_event_loop.fds + i + 1, global_event_loop.fd_entries.size - i); global_event_loop.fds = (struct pollfd *) realloc(global_event_loop.fds, sizeof(struct pollfd) * (global_event_loop.fd_entries.size)); i--; } } } size_t i; struct timeval now; int diff; timeout = global_event_loop.min_timer_value; gettimeofday(&now, NULL); for (i = 0; i < global_event_loop.timer_entries.size; i++) { struct event_loop_timer_entry *timer_entry = ((struct event_loop_timer_entry *) global_event_loop.timer_entries.buffer) + i; if (timer_entry->next_run.tv_sec < now.tv_sec || (timer_entry->next_run.tv_sec == now.tv_sec && timer_entry->next_run.tv_usec <= now.tv_usec)) { DPRINTF("Running timer due to expiry"); (*timer_entry->callback)(timer_entry->user_param); add_time(&now, &timer_entry->next_run, timer_entry->ms_timeout); } diff = (timer_entry->next_run.tv_sec - now.tv_sec) * 1000 + (timer_entry->next_run.tv_usec - now.tv_usec) / 1000; if (diff < timeout && diff != 0) timeout = diff; } } return 0; }