Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

crash when different vm threads try to update same metric fixed

  • Loading branch information...
commit 258dbc0f62a2a9203bdc8f5f5830c0f3ab9493f2 1 parent d21a65b
@petrkozorezov authored
Showing with 34 additions and 2 deletions.
  1. +34 −2 c_src/basho_metrics_nifs.cpp
View
36 c_src/basho_metrics_nifs.cpp
@@ -29,6 +29,9 @@
#include <cmath>
#include <vector>
#include <cstring>
+extern "C" {
+ #include <pthread.h>
+}
static ErlNifResourceType* histogram_RESOURCE;
static ErlNifResourceType* meter_RESOURCE;
@@ -38,12 +41,14 @@ static const unsigned long DEFAULT_METER_TICK_INTERVAL = 1000;
struct meter_handle
{
+ pthread_mutex_t m;
unsigned long tick_interval;
meter<> *p;
};
struct histogram_handle
{
+ pthread_mutex_t m;
std::size_t size;
histogram<> *p;
};
@@ -148,6 +153,7 @@ ERL_NIF_TERM histogram_new(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
if (enif_is_list(env, argv[0]))
{
memset(handle, '\0', sizeof(histogram_handle));
+ pthread_mutex_init(&(handle->m), NULL);
handle->size = DEFAULT_RESERVOIR_SIZE;
fold(env, argv[0], parse_histogram_option, *handle);
handle->p = new histogram<>(handle->size);
@@ -166,7 +172,9 @@ ERL_NIF_TERM histogram_clear(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
histogram_handle* handle;
if (enif_get_resource(env,argv[0],histogram_RESOURCE,(void**)&handle))
{
+ pthread_mutex_lock(&(handle->m));
handle->p->clear();
+ pthread_mutex_unlock(&(handle->m));
return ATOM_OK;
}
else
@@ -182,7 +190,9 @@ ERL_NIF_TERM histogram_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
if (enif_get_resource(env,argv[0],histogram_RESOURCE,(void**)&handle) &&
enif_get_ulong(env, argv[1], &sample))
{
+ pthread_mutex_lock(&(handle->m));
handle->p->update(sample);
+ pthread_mutex_unlock(&(handle->m));
return ATOM_OK;
}
else
@@ -196,12 +206,16 @@ ERL_NIF_TERM histogram_stats(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
histogram_handle* handle;
if (enif_get_resource(env,argv[0],histogram_RESOURCE,(void**)&handle))
{
+ pthread_mutex_lock(&(handle->m));
+
std::vector<double> percentiles;
percentiles.push_back(0.500);
percentiles.push_back(0.950);
percentiles.push_back(0.990);
std::vector<double> scores(handle->p->percentiles(percentiles));
- return enif_make_list8(env,
+
+ ERL_NIF_TERM result =
+ enif_make_list8(env,
STAT_TUPLE(ATOM_MIN, handle->p->min()),
STAT_TUPLE(ATOM_MAX, handle->p->max()),
STAT_TUPLE(ATOM_MEAN, handle->p->mean()),
@@ -211,6 +225,8 @@ ERL_NIF_TERM histogram_stats(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
STAT_TUPLE(ATOM_P95, scores[1]),
STAT_TUPLE(ATOM_P99, scores[2]));
+ pthread_mutex_unlock(&(handle->m));
+ return result;
}
else
return enif_make_badarg(env);
@@ -224,6 +240,7 @@ ERL_NIF_TERM meter_new(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
if (enif_is_list(env, argv[0]))
{
memset(handle, '\0', sizeof(meter_handle));
+ pthread_mutex_init(&(handle->m), NULL);
handle->tick_interval = DEFAULT_METER_TICK_INTERVAL;
fold(env, argv[0], parse_meter_option, *handle);
handle->p = new meter<>(handle->tick_interval);
@@ -242,7 +259,9 @@ ERL_NIF_TERM meter_tick(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
meter_handle *handle;
if (enif_get_resource(env,argv[0],meter_RESOURCE,(void**)&handle))
{
+ pthread_mutex_lock(&(handle->m));
handle->p->tick();
+ pthread_mutex_unlock(&(handle->m));
return ATOM_OK;
}
else
@@ -258,7 +277,9 @@ ERL_NIF_TERM meter_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
if (enif_get_resource(env,argv[0],meter_RESOURCE,(void**)&handle) &&
enif_get_ulong(env, argv[1], &sample))
{
+ pthread_mutex_lock(&(handle->m));
handle->p->mark(sample);
+ pthread_mutex_unlock(&(handle->m));
return ATOM_OK;
}
else
@@ -272,13 +293,18 @@ ERL_NIF_TERM meter_stats(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
meter_handle* handle;
if (enif_get_resource(env,argv[0],meter_RESOURCE,(void**)&handle))
{
- return enif_make_list4(env,
+ pthread_mutex_lock(&(handle->m));
+
+ ERL_NIF_TERM result =
+ enif_make_list4(env,
enif_make_tuple2(env,ATOM_COUNT,
enif_make_ulong(env, handle->p->count())),
enif_make_tuple2(env,ATOM_ONE,
enif_make_double(env,handle->p->one())),
enif_make_tuple2(env,ATOM_FIVE,enif_make_double(env, handle->p->five())),
enif_make_tuple2(env,ATOM_FIFTEEN,enif_make_double(env, handle->p->fifteen())));
+ pthread_mutex_unlock(&(handle->m));
+ return result;
}
else
return enif_make_badarg(env);
@@ -287,12 +313,18 @@ ERL_NIF_TERM meter_stats(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
static void histogram_resource_cleanup(ErlNifEnv* env, void* arg)
{
histogram_handle* handle = (histogram_handle*)arg;
+
+ pthread_mutex_destroy(&(handle->m));
+
delete handle->p;
}
static void meter_resource_cleanup(ErlNifEnv* env, void* arg)
{
meter_handle* handle = (meter_handle*)arg;
+
+ pthread_mutex_destroy(&(handle->m));
+
delete handle->p;
}
Please sign in to comment.
Something went wrong with that request. Please try again.