1515 */
1616package org.jitsi.utils.logging2
1717
18+ import java.lang.ref.Cleaner
1819import java.lang.ref.WeakReference
1920
2021/* *
@@ -48,23 +49,30 @@ class LogContext private constructor(
4849 var formattedContext: String = formatContext(ancestorsContext + context)
4950 private set
5051
51- /* * Child [LogContext]s of this [LogContext] (which will be notified anytime this context changes) */
52- private val childContexts: MutableList <WeakReference <LogContext >> = ArrayList ()
53-
5452 @Synchronized
5553 private fun updateFormattedContext () {
5654 val combined = ancestorsContext + context
5755 formattedContext = formatContext(combined)
5856 updateChildren(combined)
5957 }
6058
59+ /* * Child [LogContext]s of this [LogContext] (which will be notified anytime this context changes) */
60+ private val childContexts = mutableMapOf<Long , WeakReference <LogContext >>()
61+
62+ private var childCounter = 0L
63+
6164 @Synchronized
6265 fun createSubContext (childContextData : Map <String , String >) = LogContext (
6366 ancestorsContext + context,
6467 childContextData
6568 ).also {
66- childContexts.removeIf { r -> r.get() == null }
67- childContexts.add(WeakReference (it))
69+ val count = childCounter++
70+ childContexts[count] = WeakReference (it)
71+ CLEANER .register(it) {
72+ synchronized(this @LogContext) {
73+ childContexts.remove(count)
74+ }
75+ }
6876 }
6977
7078 fun addContext (key : String , value : String ) = addContext(mapOf (key to value))
@@ -83,9 +91,8 @@ class LogContext private constructor(
8391
8492 /* * Notify children of changes in this context */
8593 @Synchronized
86- private fun updateChildren (newAncestorContext : Map <String , String >) = childContexts.apply {
87- removeIf { it.get() == null }
88- forEach { it.get()?.ancestorsContext = newAncestorContext }
94+ private fun updateChildren (newAncestorContext : Map <String , String >) = childContexts.values.forEach {
95+ it.get()?.ancestorsContext = newAncestorContext
8996 }
9097
9198 override fun toString () = formattedContext
@@ -94,6 +101,8 @@ class LogContext private constructor(
94101 const val CONTEXT_START_TOKEN = " ["
95102 const val CONTEXT_END_TOKEN = " ]"
96103
104+ private val CLEANER = Cleaner .create()
105+
97106 private fun formatContext (context : Map <String , String >): String {
98107 val s = context.entries.joinToString(separator = " " ) { " ${it.key} =${it.value} " }
99108 return if (s.isEmpty()) " " else " $CONTEXT_START_TOKEN$s$CONTEXT_END_TOKEN "
0 commit comments