Commit ef0f3a1e authored by Marius Wachtler's avatar Marius Wachtler

PerThreadSet: make sure that the pthread setspecific callback does not access destroyed memory

This caused the 'self->map.size() == self->map_elts' assert we saw sometimes on travis CI
parent 013d46eb
...@@ -182,6 +182,7 @@ private: ...@@ -182,6 +182,7 @@ private:
std::tuple<CtorArgs...> ctor_args; std::tuple<CtorArgs...> ctor_args;
#ifndef NDEBUG #ifndef NDEBUG
int map_elts = 0; int map_elts = 0;
bool got_already_destroyed = false;
#endif #endif
static void dtor(void* val) { static void dtor(void* val) {
...@@ -190,6 +191,8 @@ private: ...@@ -190,6 +191,8 @@ private:
auto* self = s->self; auto* self = s->self;
ASSERT(!self->got_already_destroyed, "");
LOCK_REGION(&self->lock); LOCK_REGION(&self->lock);
assert(s->my_tid == pthread_self()); assert(s->my_tid == pthread_self());
...@@ -237,6 +240,15 @@ public: ...@@ -237,6 +240,15 @@ public:
ASSERT(this->map.size() == this->map_elts, "%ld %d", this->map.size(), this->map_elts); ASSERT(this->map.size() == this->map_elts, "%ld %d", this->map.size(), this->map_elts);
} }
~PerThreadSet() {
LOCK_REGION(&lock);
ASSERT(this->map.size() == this->map_elts, "%ld %d", this->map.size(), this->map_elts);
pthread_key_delete(pthread_key);
#ifndef NDEBUG
got_already_destroyed = true;
#endif
}
void forEachValue(std::function<void(T*)> f) { void forEachValue(std::function<void(T*)> f) {
LOCK_REGION(&lock); LOCK_REGION(&lock);
ASSERT(this->map.size() == this->map_elts, "%ld %d", this->map.size(), this->map_elts); ASSERT(this->map.size() == this->map_elts, "%ld %d", this->map.size(), this->map_elts);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment