Browse Source

change control_ng_stats into a hash and use locking and atomic ops

pull/101/head
Richard Fuchs 11 years ago
parent
commit
36c7141d53
8 changed files with 62 additions and 62 deletions
  1. +10
    -0
      daemon/aux.c
  2. +8
    -3
      daemon/aux.h
  3. +3
    -0
      daemon/call.c
  4. +3
    -1
      daemon/call.h
  5. +9
    -5
      daemon/cli.c
  6. +21
    -41
      daemon/control_ng.c
  7. +8
    -10
      daemon/control_ng.h
  8. +0
    -2
      daemon/main.c

+ 10
- 0
daemon/aux.c View File

@ -192,3 +192,13 @@ void thread_create_detach(void (*f)(void *), void *d) {
if (thread_create(thread_detach_func, dt, 1, NULL))
abort();
}
unsigned int in6_addr_hash(const void *p) {
const struct in6_addr *a = p;
return a->s6_addr32[0] ^ a->s6_addr32[3];
}
int in6_addr_eq(const void *a, const void *b) {
const struct in6_addr *A = a, *B = b;
return !memcmp(A, B, sizeof(*A));
}

+ 8
- 3
daemon/aux.h View File

@ -144,7 +144,7 @@ INLINE u_int32_t in6_to_4(const struct in6_addr *a) {
return a->s6_addr32[3];
}
INLINE void smart_ntop(char *o, struct in6_addr *a, size_t len) {
INLINE void smart_ntop(char *o, const struct in6_addr *a, size_t len) {
const char *r;
if (IN6_IS_ADDR_V4MAPPED(a))
@ -156,7 +156,7 @@ INLINE void smart_ntop(char *o, struct in6_addr *a, size_t len) {
*o = '\0';
}
INLINE char *smart_ntop_p(char *o, struct in6_addr *a, size_t len) {
INLINE char *smart_ntop_p(char *o, const struct in6_addr *a, size_t len) {
int l;
if (IN6_IS_ADDR_V4MAPPED(a)) {
@ -178,7 +178,7 @@ INLINE char *smart_ntop_p(char *o, struct in6_addr *a, size_t len) {
}
}
INLINE void smart_ntop_port(char *o, struct sockaddr_in6 *a, size_t len) {
INLINE void smart_ntop_port(char *o, const struct sockaddr_in6 *a, size_t len) {
char *e;
e = smart_ntop_p(o, &a->sin6_addr, len);
@ -483,4 +483,9 @@ INLINE void g_queue_append(GQueue *dst, const GQueue *src) {
g_queue_push_tail(dst, l->data);
}
unsigned int in6_addr_hash(const void *p);
int in6_addr_eq(const void *a, const void *b);
#endif

+ 3
- 0
daemon/call.c View File

@ -1426,6 +1426,9 @@ struct callmaster *callmaster_new(struct poller *p) {
mutex_init(&c->totalstats_lock);
c->totalstats.started = poller_now;
mutex_init(&c->cngs_lock);
c->cngs_hash = g_hash_table_new(in6_addr_hash, in6_addr_eq);
return c;
fail:


+ 3
- 1
daemon/call.h View File

@ -413,7 +413,9 @@ struct callmaster {
mutex_t totalstats_lock; /* for both of them */
struct totalstats totalstats;
struct totalstats totalstats_interval;
struct control_ng_stats* control_ng_stats;
/* control_ng_stats stuff */
mutex_t cngs_lock;
GHashTable *cngs_hash;
struct poller *poller;
pcre *info_re;


+ 9
- 5
daemon/cli.c View File

@ -60,15 +60,18 @@ static void cli_incoming_list_totals(char* buffer, int len, struct callmaster* m
printlen = snprintf(replybuffer,(outbufend-replybuffer), " %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s \n",
"Proxy", "Offer", "Answer", "Delete", "Ping", "List", "Query", "Errors");
ADJUSTLEN(printlen,outbufend,replybuffer);
struct control_ng_stats* cur = m->control_ng_stats;
if (!cur) {
mutex_lock(&m->cngs_lock);
GList *list = g_hash_table_get_values(m->cngs_hash);
if (!list) {
printlen = snprintf(replybuffer,(outbufend-replybuffer), "\n No proxies have yet tried to send data.");
ADJUSTLEN(printlen,outbufend,replybuffer);
}
while (cur) {
for (GList *l = list; l; l = l->next) {
struct control_ng_stats* cur = l->data;
char buf[128]; memset(&buf,0,128);
smart_ntop_p(buf, &(cur->proxy.sin6_addr), sizeof(buf));
smart_ntop_p(buf, &(cur->proxy), sizeof(buf));
printlen = snprintf(replybuffer,(outbufend-replybuffer), " %10s | %10u | %10u | %10u | %10u | %10u | %10u | %10u \n",
buf,
@ -80,10 +83,11 @@ static void cli_incoming_list_totals(char* buffer, int len, struct callmaster* m
cur->query,
cur->errors);
ADJUSTLEN(printlen,outbufend,replybuffer);
cur = cur->next;
}
printlen = snprintf(replybuffer,(outbufend-replybuffer), "\n\n");
ADJUSTLEN(printlen,outbufend,replybuffer);
mutex_unlock(&m->cngs_lock);
g_list_free(list);
}
static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) {


+ 21
- 41
daemon/control_ng.c View File

@ -56,41 +56,21 @@ static void pretty_print(bencode_item_t *el, GString *s) {
}
}
struct control_ng_stats* get_control_ng_stats(struct control_ng* c, struct sockaddr_in6* sin) {
// seems to be the first address
if (!c->callmaster->control_ng_stats) {
c->callmaster->control_ng_stats = malloc(sizeof(struct control_ng_stats));
memset(c->callmaster->control_ng_stats,0,sizeof(struct control_ng_stats));
memcpy(&(c->callmaster->control_ng_stats->proxy),sin,sizeof(struct sockaddr_in6));
struct control_ng_stats* get_control_ng_stats(struct control_ng* c, const struct in6_addr *addr) {
struct callmaster *m = c->callmaster;
struct control_ng_stats* cur;
mutex_lock(&m->cngs_lock);
cur = g_hash_table_lookup(m->cngs_hash, addr);
if (!cur) {
cur = g_slice_alloc0(sizeof(struct control_ng_stats));
cur->proxy = *addr;
char buf[128]; memset(&buf,0,128);
smart_ntop_p(buf, &sin->sin6_addr, sizeof(buf));
ilog(LOG_INFO,"Adding a first proxy for control ng stats:%s\n",buf);
return c->callmaster->control_ng_stats;
}
struct control_ng_stats* cur = c->callmaster->control_ng_stats;
struct control_ng_stats* last;
while (cur) {
last = cur;
if (memcmp((const void*)(&(cur->proxy.sin6_addr)),(const void*)(&(sin->sin6_addr)),sizeof(struct in6_addr))==0) {
ilog(LOG_DEBUG,"Already found proxy for control ng stats.\n");
return cur;
}
cur = cur->next;
smart_ntop_p(buf, addr, sizeof(buf));
ilog(LOG_DEBUG,"Adding a proxy for control ng stats:%s",buf);
g_hash_table_insert(m->cngs_hash, &cur->proxy, cur);
}
// add a new one
char buf[128]; memset(&buf,0,128);
smart_ntop_p(buf, &sin->sin6_addr, sizeof(buf));
ilog(LOG_INFO,"Adding a new proxy for control ng stats:%s\n",buf);
cur = malloc(sizeof(struct control_ng_stats));
memset(cur,0,sizeof(struct control_ng_stats));
memcpy(cur,sin,sizeof(struct sockaddr_in6));
last->next = cur;
mutex_unlock(&m->cngs_lock);
return cur;
}
@ -104,7 +84,7 @@ static void control_ng_incoming(struct obj *obj, str *buf, struct sockaddr_in6 *
struct iovec iov[3];
GString *log_str;
struct control_ng_stats* cur = get_control_ng_stats(c,sin);
struct control_ng_stats* cur = get_control_ng_stats(c,&sin->sin6_addr);
str_chr_str(&data, buf, ' ');
if (!data.s || data.s == buf->s) {
@ -150,28 +130,28 @@ static void control_ng_incoming(struct obj *obj, str *buf, struct sockaddr_in6 *
errstr = NULL;
if (!str_cmp(&cmd, "ping")) {
bencode_dictionary_add_string(resp, "result", "pong");
cur->ping++;
g_atomic_int_inc(&cur->ping);
}
else if (!str_cmp(&cmd, "offer")) {
errstr = call_offer_ng(dict, c->callmaster, resp, addr, sin);
cur->offer++;
g_atomic_int_inc(&cur->offer);
}
else if (!str_cmp(&cmd, "answer")) {
errstr = call_answer_ng(dict, c->callmaster, resp);
cur->answer++;
g_atomic_int_inc(&cur->answer);
}
else if (!str_cmp(&cmd, "delete")) {
errstr = call_delete_ng(dict, c->callmaster, resp);
cur->delete++;
g_atomic_int_inc(&cur->delete);
}
else if (!str_cmp(&cmd, "query")) {
errstr = call_query_ng(dict, c->callmaster, resp);
cur->query++;
g_atomic_int_inc(&cur->query);
}
#if GLIB_CHECK_VERSION(2,16,0)
else if (!str_cmp(&cmd, "list")) {
errstr = call_list_ng(dict, c->callmaster, resp);
cur->list++;
g_atomic_int_inc(&cur->list);
}
#endif
else
@ -186,7 +166,7 @@ err_send:
ilog(LOG_WARNING, "Protocol error in packet from %s: %s ["STR_FORMAT"]", addr, errstr, STR_FMT(&data));
bencode_dictionary_add_string(resp, "result", "error");
bencode_dictionary_add_string(resp, "error-reason", errstr);
cur->errors++;
g_atomic_int_inc(&cur->errors);
goto send_resp;
send_resp:


+ 8
- 10
daemon/control_ng.h View File

@ -10,15 +10,14 @@ struct poller;
struct callmaster;
struct control_ng_stats {
struct sockaddr_in6 proxy;
u_int32_t ping;
u_int32_t offer;
u_int32_t answer;
u_int32_t delete;
u_int32_t query;
u_int32_t list;
u_int32_t errors;
struct control_ng_stats* next;
struct in6_addr proxy;
int ping;
int offer;
int answer;
int delete;
int query;
int list;
int errors;
};
struct control_ng {
@ -30,5 +29,4 @@ struct control_ng {
struct control_ng *control_ng_new(struct poller *, struct in6_addr, u_int16_t, struct callmaster *);
#endif

+ 0
- 2
daemon/main.c View File

@ -620,8 +620,6 @@ no_kernel:
if (redis_restore(ctx->m, mc.redis))
die("Refusing to continue without working Redis database");
ZERO(ctx->m->control_ng_stats);
}
static void timer_loop(void *d) {


Loading…
Cancel
Save