Workaround data race on cyclic collector deinit
This commit is contained in:
committed by
SvyatoslavScherbina
parent
60108071dd
commit
b2d3bcf6fd
@@ -134,6 +134,12 @@ class CyclicCollector {
|
|||||||
CHECK_CALL(pthread_create(&gcThread_, nullptr, gcWorkerRoutine, this), "Cannot start collector thread")
|
CHECK_CALL(pthread_create(&gcThread_, nullptr, gcWorkerRoutine, this), "Cannot start collector thread")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
Locker lock(&lock_);
|
||||||
|
rootset_.clear();
|
||||||
|
toRelease_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void terminate() {
|
void terminate() {
|
||||||
{
|
{
|
||||||
Locker locker(&lock_);
|
Locker locker(&lock_);
|
||||||
@@ -436,62 +442,74 @@ void cyclicDeinit() {
|
|||||||
auto* local = cyclicCollector;
|
auto* local = cyclicCollector;
|
||||||
local->terminate();
|
local->terminate();
|
||||||
cyclicCollector = nullptr;
|
cyclicCollector = nullptr;
|
||||||
konanDestructInstance(local);
|
// Workaround data race with threads non-atomically reading and then using [cyclicCollector].
|
||||||
|
// konanDestructInstance(local);
|
||||||
|
// Note: memory leaks here indeed, but usually it happens once per application.
|
||||||
|
// Make best effort to clean some memory:
|
||||||
|
local->clear();
|
||||||
#endif // WITH_WORKERS
|
#endif // WITH_WORKERS
|
||||||
}
|
}
|
||||||
|
|
||||||
void cyclicAddWorker(void* worker) {
|
void cyclicAddWorker(void* worker) {
|
||||||
#if WITH_WORKERS
|
#if WITH_WORKERS
|
||||||
if (cyclicCollector)
|
auto* local = cyclicCollector;
|
||||||
cyclicCollector->addWorker(worker);
|
if (local)
|
||||||
|
local->addWorker(worker);
|
||||||
#endif // WITH_WORKERS
|
#endif // WITH_WORKERS
|
||||||
}
|
}
|
||||||
|
|
||||||
void cyclicRemoveWorker(void* worker) {
|
void cyclicRemoveWorker(void* worker) {
|
||||||
#if WITH_WORKERS
|
#if WITH_WORKERS
|
||||||
if (cyclicCollector)
|
auto* local = cyclicCollector;
|
||||||
cyclicCollector->removeWorker(worker);
|
if (local)
|
||||||
|
local->removeWorker(worker);
|
||||||
#endif // WITH_WORKERS
|
#endif // WITH_WORKERS
|
||||||
}
|
}
|
||||||
|
|
||||||
void cyclicCollectorCallback(void* worker) {
|
void cyclicCollectorCallback(void* worker) {
|
||||||
#if WITH_WORKERS
|
#if WITH_WORKERS
|
||||||
if (cyclicCollector)
|
auto* local = cyclicCollector;
|
||||||
cyclicCollector->collectorCallaback(worker);
|
if (local)
|
||||||
|
local->collectorCallaback(worker);
|
||||||
#endif // WITH_WORKERS
|
#endif // WITH_WORKERS
|
||||||
}
|
}
|
||||||
|
|
||||||
void cyclicScheduleGarbageCollect() {
|
void cyclicScheduleGarbageCollect() {
|
||||||
#if WITH_WORKERS
|
#if WITH_WORKERS
|
||||||
if (cyclicCollector)
|
auto* local = cyclicCollector;
|
||||||
cyclicCollector->scheduleGarbageCollect();
|
if (local)
|
||||||
|
local->scheduleGarbageCollect();
|
||||||
#endif // WITH_WORKERS
|
#endif // WITH_WORKERS
|
||||||
}
|
}
|
||||||
|
|
||||||
void cyclicAddAtomicRoot(ObjHeader* obj) {
|
void cyclicAddAtomicRoot(ObjHeader* obj) {
|
||||||
#if WITH_WORKERS
|
#if WITH_WORKERS
|
||||||
if (cyclicCollector)
|
auto* local = cyclicCollector;
|
||||||
cyclicCollector->addRoot(obj);
|
if (local)
|
||||||
|
local->addRoot(obj);
|
||||||
#endif // WITH_WORKERS
|
#endif // WITH_WORKERS
|
||||||
}
|
}
|
||||||
|
|
||||||
void cyclicRemoveAtomicRoot(ObjHeader* obj) {
|
void cyclicRemoveAtomicRoot(ObjHeader* obj) {
|
||||||
#if WITH_WORKERS
|
#if WITH_WORKERS
|
||||||
if (cyclicCollector)
|
auto* local = cyclicCollector;
|
||||||
cyclicCollector->removeRoot(obj);
|
if (local)
|
||||||
|
local->removeRoot(obj);
|
||||||
#endif // WITH_WORKERS
|
#endif // WITH_WORKERS
|
||||||
}
|
}
|
||||||
|
|
||||||
void cyclicMutateAtomicRoot(ObjHeader* newValue) {
|
void cyclicMutateAtomicRoot(ObjHeader* newValue) {
|
||||||
#if WITH_WORKERS
|
#if WITH_WORKERS
|
||||||
if (cyclicCollector)
|
auto* local = cyclicCollector;
|
||||||
cyclicCollector->mutateRoot(newValue);
|
if (local)
|
||||||
|
local->mutateRoot(newValue);
|
||||||
#endif // WITH_WORKERS
|
#endif // WITH_WORKERS
|
||||||
}
|
}
|
||||||
|
|
||||||
void cyclicLocalGC() {
|
void cyclicLocalGC() {
|
||||||
#if WITH_WORKERS
|
#if WITH_WORKERS
|
||||||
if (cyclicCollector)
|
auto* local = cyclicCollector;
|
||||||
cyclicCollector->localGC();
|
if (local)
|
||||||
|
local->localGC();
|
||||||
#endif // WITH_WORKERS
|
#endif // WITH_WORKERS
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user