|
|
|
|
@ -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)
|
|
|
|
|
|