Fix race condition in DB engine API (#6079)
Markos Fountoulakis committed
May 22, 2019 at 13:27 UTC
908d5c78faf0356ec2bfe91db0eae06f47785b39
2 files changed
+8
-1
database/engine/pagecache.h
+1
@@ -114,6 +114,7 @@ extern void pg_cache_replaceQ_delete(struct rrdengine_instance *ctx,
114
extern void pg_cache_replaceQ_set_hot(struct rrdengine_instance *ctx,
115
struct rrdeng_page_cache_descr *descr);
116
extern struct rrdeng_page_cache_descr *pg_cache_create_descr(void);
117
+extern int pg_cache_try_get_unsafe(struct rrdeng_page_cache_descr *descr, int exclusive_access);
118
extern void pg_cache_put_unsafe(struct rrdeng_page_cache_descr *descr);
119
extern void pg_cache_put(struct rrdeng_page_cache_descr *descr);
120
extern void pg_cache_insert(struct rrdengine_instance *ctx, struct pg_cache_page_index *index,
database/engine/rrdengineapi.c
+7
-1
@@ -76,11 +76,17 @@ void rrdeng_store_metric_next(RRDDIM *rd, usec_t point_in_time, storage_number n
76
if (descr) {
77
descr->handle = NULL;
78
if (descr->page_length) {
79
+ int ret;
80
+
81
#ifdef NETDATA_INTERNAL_CHECKS
82
rrd_stat_atomic_add(&ctx->stats.metric_API_producers, -1);
83
#endif
84
/* added 1 extra reference to keep 2 dirty pages pinned per metric, expected refcnt = 2 */
83
- ++descr->refcnt;
85
+ uv_mutex_lock(&descr->mutex);
86
+ ret = pg_cache_try_get_unsafe(descr, 0);
87
+ uv_mutex_unlock(&descr->mutex);
88
+ assert (1 == ret);
89
+
90
rrdeng_commit_page(ctx, descr, handle->page_correlation_id);
91
if (handle->prev_descr) {
92
/* unpin old second page */