|
|
|
@ -11,6 +11,7 @@ |
|
|
|
#include <errno.h> |
|
|
|
#include <sys/epoll.h> |
|
|
|
#include <glib.h> |
|
|
|
#include <sys/syscall.h> |
|
|
|
#include <sys/time.h> |
|
|
|
#include <main.h> |
|
|
|
#include <redis.h> |
|
|
|
@ -50,9 +51,71 @@ struct poller { |
|
|
|
GSList *timers_del; |
|
|
|
}; |
|
|
|
|
|
|
|
struct poller_map { |
|
|
|
mutex_t lock; |
|
|
|
GHashTable *table; |
|
|
|
}; |
|
|
|
|
|
|
|
struct poller_map *poller_map_new(void) { |
|
|
|
struct poller_map *p; |
|
|
|
|
|
|
|
p = malloc(sizeof(*p)); |
|
|
|
memset(p, 0, sizeof(*p)); |
|
|
|
mutex_init(&p->lock); |
|
|
|
p->table = g_hash_table_new(g_direct_hash, g_direct_equal); |
|
|
|
|
|
|
|
return p; |
|
|
|
} |
|
|
|
|
|
|
|
long poller_map_add(struct poller_map *map) { |
|
|
|
long tid = -1; |
|
|
|
struct poller *p; |
|
|
|
if (!map) |
|
|
|
return tid; |
|
|
|
tid = syscall(SYS_gettid); |
|
|
|
|
|
|
|
mutex_lock(&map->lock); |
|
|
|
p = poller_new(); |
|
|
|
g_hash_table_insert(map->table, (gpointer)tid, p); |
|
|
|
mutex_unlock(&map->lock); |
|
|
|
return tid; |
|
|
|
} |
|
|
|
|
|
|
|
struct poller *poller_map_get(struct poller_map *map) { |
|
|
|
if (!map) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
struct poller *p = NULL; |
|
|
|
long tid = syscall(SYS_gettid); |
|
|
|
mutex_lock(&map->lock); |
|
|
|
p = g_hash_table_lookup(map->table, (gpointer)tid); |
|
|
|
if (!p) { |
|
|
|
gpointer *arr = g_hash_table_get_keys_as_array(map->table, NULL); |
|
|
|
GRand *rnd = g_rand_new(); |
|
|
|
p = g_hash_table_lookup(map->table, arr[g_rand_int_range(rnd, 0, g_hash_table_size(map->table))]); |
|
|
|
g_rand_free(rnd); |
|
|
|
} |
|
|
|
mutex_unlock(&map->lock); |
|
|
|
return p; |
|
|
|
} |
|
|
|
|
|
|
|
static void poller_map_free_poller(gpointer k, gpointer v, gpointer d) { |
|
|
|
struct poller *p = (struct poller *)v; |
|
|
|
poller_free(&p); |
|
|
|
} |
|
|
|
|
|
|
|
void poller_map_free(struct poller_map **map) { |
|
|
|
struct poller_map *m = *map; |
|
|
|
if (!m) |
|
|
|
return; |
|
|
|
mutex_lock(&m->lock); |
|
|
|
g_hash_table_foreach(m->table, poller_map_free_poller, NULL); |
|
|
|
g_hash_table_destroy(m->table); |
|
|
|
mutex_unlock(&m->lock); |
|
|
|
mutex_destroy(&m->lock); |
|
|
|
free(m); |
|
|
|
*map = NULL; |
|
|
|
} |
|
|
|
|
|
|
|
struct poller *poller_new(void) { |
|
|
|
struct poller *p; |
|
|
|
@ -537,7 +600,31 @@ now: |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void sleep_ms(int ms) { |
|
|
|
struct timespec deadline; |
|
|
|
long next_tick; |
|
|
|
clock_gettime(CLOCK_MONOTONIC, &deadline); |
|
|
|
|
|
|
|
next_tick = (deadline.tv_sec * 1000000000L + deadline.tv_nsec) + ms * 1000000; |
|
|
|
deadline.tv_sec = next_tick / 1000000000L; |
|
|
|
deadline.tv_nsec = next_tick % 1000000000L; |
|
|
|
|
|
|
|
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &deadline, NULL); |
|
|
|
} |
|
|
|
|
|
|
|
void poller_loop(void *d) { |
|
|
|
struct poller_map *map = d; |
|
|
|
poller_map_add(map); |
|
|
|
struct poller *p = poller_map_get(map); |
|
|
|
|
|
|
|
while (!rtpe_shutdown) { |
|
|
|
int ret = poller_poll(p, 100); |
|
|
|
if (ret < 0) |
|
|
|
sleep_ms(10); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void poller_loop2(void *d) { |
|
|
|
struct poller *p = d; |
|
|
|
|
|
|
|
while (!rtpe_shutdown) |
|
|
|
|