Permalink
Browse files

bug 1512 - don't leak timeout_event registrations

Previously, if the code encountered a not-my-vbucket error
and wanted to retry the command, it would leak a libevent evtimer
registration, which eventually led to moxi pegging 100% cpu
with all the timer events.

Change-Id: I3d966246713b2c095b17ff2ffacb9943e2b90c87
Reviewed-on: http://review.northscale.com:8080/813
Reviewed-by: Eric Lambert <eric.d.lambert@gmail.com>
Tested-by: Steve Yen <steve.yen@gmail.com>
  • Loading branch information...
1 parent e375968 commit 2910f247eb9058155f0dcd2bccfec4823a4006da @steveyen steveyen committed Jun 22, 2010
Showing with 13 additions and 8 deletions.
  1. +13 −8 cproxy.c
View
@@ -662,6 +662,17 @@ bool cproxy_release_downstream(downstream *d, bool force) {
fprintf(stderr, "release_downstream\n");
}
+ // Always release the timeout_event, even if we're going to retry,
+ // to avoid pegging CPU with leaked timeout_events.
+ //
+ if (d->timeout_tv.tv_sec != 0 ||
+ d->timeout_tv.tv_usec != 0) {
+ evtimer_del(&d->timeout_event);
+ }
+
+ d->timeout_tv.tv_sec = 0;
+ d->timeout_tv.tv_usec = 0;
+
// If we need to retry the command, we do so here,
// keeping the same downstream that would otherwise
// be released.
@@ -673,6 +684,8 @@ bool cproxy_release_downstream(downstream *d, bool force) {
// But, we can stop retrying if we've tried each server twice.
//
+ // TODO: Add a stat for retrying.
+ //
int max_retries = mcs_server_count(&d->mst) * 2;
if (d->upstream_retries <= max_retries) {
@@ -754,14 +767,6 @@ bool cproxy_release_downstream(downstream *d, bool force) {
d->merger = NULL;
}
- if (d->timeout_tv.tv_sec != 0 ||
- d->timeout_tv.tv_usec != 0) {
- evtimer_del(&d->timeout_event);
- }
-
- d->timeout_tv.tv_sec = 0;
- d->timeout_tv.tv_usec = 0;
-
d->upstream_conn = NULL;
d->upstream_suffix = NULL; // No free(), expecting a static string.
d->upstream_retry = 0;

0 comments on commit 2910f24

Please sign in to comment.