Kris Wong
10/30/2019, 8:00 PMexecute
?Kris Wong
10/30/2019, 8:04 PMKris Wong
10/30/2019, 8:05 PMkpgalligan
10/30/2019, 8:05 PMKris Wong
10/30/2019, 8:05 PMkpgalligan
10/30/2019, 8:06 PMKris Wong
10/30/2019, 8:06 PMKris Wong
10/30/2019, 8:06 PMkpgalligan
10/30/2019, 8:07 PMkpgalligan
10/30/2019, 8:07 PMKris Wong
10/30/2019, 8:07 PMprivate val _worker = lazy { Worker.start() }
private val worker by _worker
private val buffer by lazy {
check(_worker.isInitialized() && Worker.current == worker)
val buffer = MemoryMappedRingBuffer(1024, "")
buffer.open()
buffer
}
actual fun log(entry: LogEntry) {
worker.execute(TransferMode.SAFE, { entry.freeze() }) {
buffer.write(entry.format())
}
}
actual fun log(level: LogLevel, subsystem: Subsystem, message: String, context: LogContext?) {
worker.execute(TransferMode.SAFE, { LogEntry(level, subsystem, message, context) }) { entry ->
buffer.write(entry.format())
}
}
kpgalligan
10/30/2019, 8:12 PMbuffer
is created lazily by the lambda, but it’s a member of a class that is presumably referenced by other threads. buffer
needs to be thread local or frozen.Arkadii Ivanov
10/30/2019, 8:51 PMKris Wong
10/30/2019, 8:58 PMbuffer
Kris Wong
10/30/2019, 8:58 PMArkadii Ivanov
10/30/2019, 8:59 PMKris Wong
10/30/2019, 8:59 PMArkadii Ivanov
10/30/2019, 9:00 PMKris Wong
10/30/2019, 9:00 PMArkadii Ivanov
10/30/2019, 9:01 PMkpgalligan
10/30/2019, 9:01 PMArkadii Ivanov
10/30/2019, 9:01 PMKris Wong
10/30/2019, 9:03 PMArkadii Ivanov
10/30/2019, 9:04 PMArkadii Ivanov
10/30/2019, 9:05 PMkpgalligan
10/30/2019, 9:05 PMKris Wong
10/30/2019, 9:06 PMKris Wong
10/30/2019, 9:06 PMkpgalligan
10/30/2019, 9:06 PMkpgalligan
10/30/2019, 9:08 PMKris Wong
10/30/2019, 9:08 PMKris Wong
10/30/2019, 9:08 PMkpgalligan
10/30/2019, 9:09 PMKris Wong
10/30/2019, 9:10 PMkpgalligan
10/30/2019, 9:10 PMKris Wong
10/30/2019, 9:11 PMKris Wong
10/30/2019, 9:11 PMkpgalligan
10/30/2019, 9:11 PMKris Wong
10/30/2019, 9:12 PMKris Wong
10/30/2019, 9:16 PMkpgalligan
10/30/2019, 9:17 PMkpgalligan
10/30/2019, 9:18 PMKris Wong
10/30/2019, 9:18 PMKris Wong
10/30/2019, 9:19 PMKris Wong
10/30/2019, 9:20 PMkpgalligan
10/30/2019, 9:20 PMkpgalligan
10/30/2019, 9:20 PMKris Wong
10/30/2019, 9:21 PMKris Wong
10/30/2019, 9:21 PMArkadii Ivanov
10/30/2019, 9:22 PMkpgalligan
10/30/2019, 9:22 PMKris Wong
10/30/2019, 9:23 PMkpgalligan
10/30/2019, 9:24 PMKris Wong
10/30/2019, 9:25 PMkpgalligan
10/30/2019, 9:26 PMkpgalligan
10/30/2019, 9:27 PMKris Wong
10/30/2019, 9:28 PMKris Wong
10/30/2019, 9:29 PMkpgalligan
10/30/2019, 9:35 PMArkadii Ivanov
10/30/2019, 9:35 PMKris Wong
10/30/2019, 9:42 PMKris Wong
10/30/2019, 9:42 PMKris Wong
10/30/2019, 9:43 PMArkadii Ivanov
10/30/2019, 9:44 PMKris Wong
10/30/2019, 9:44 PMArkadii Ivanov
10/30/2019, 9:49 PMArkadii Ivanov
10/30/2019, 9:52 PMKris Wong
10/30/2019, 10:04 PMkpgalligan
10/30/2019, 10:04 PMKris Wong
10/31/2019, 1:03 AMKris Wong
10/31/2019, 2:35 PMKris Wong
10/31/2019, 2:36 PMkpgalligan
10/31/2019, 2:38 PMKris Wong
10/31/2019, 2:38 PMkpgalligan
10/31/2019, 2:38 PMKris Wong
10/31/2019, 2:38 PMbuffer
kpgalligan
10/31/2019, 2:38 PMKris Wong
10/31/2019, 2:39 PMkpgalligan
10/31/2019, 2:39 PMKris Wong
10/31/2019, 2:39 PMKris Wong
10/31/2019, 2:39 PMkpgalligan
10/31/2019, 2:39 PMKris Wong
10/31/2019, 2:41 PMkpgalligan
10/31/2019, 2:41 PMKris Wong
10/31/2019, 2:41 PMKris Wong
10/31/2019, 2:42 PMKris Wong
10/31/2019, 2:44 PMArkadii Ivanov
10/31/2019, 2:55 PMKris Wong
10/31/2019, 2:57 PM@ThreadLocal
to compilekpgalligan
10/31/2019, 2:57 PMkpgalligan
10/31/2019, 2:58 PM@ThreadLocal
internal object TheCache {
val buffer:MemoryMappedRingBuffer = MemoryMappedRingBuffer(1024, "")
init {
buffer.open()
}
}
object LogEngine {
private val worker = Worker.start()
fun log(entry: LogEntry){
println("log called in main ${NSThread.isMainThread()}")
worker.execute(TransferMode.SAFE, { entry.freeze() }) {
TheCache.buffer.write(it.format())
}
}
fun log(){
worker.execute(TransferMode.SAFE, { LogEntry("bunch of stuff") }) {
TheCache.buffer.write(it.format())
}
}
fun flush() = worker.execute(TransferMode.SAFE, {}) { Worker.current?.processQueue() }.result
}
class MemoryMappedRingBuffer(i:Int, s:String){
fun open(){}
fun write(log:String){
println("Logging: $log, is in main thread ${NSThread.isMainThread()}, am I frozen? ${isFrozen}")
}
}
data class LogEntry(val s:String){
fun format():String = "LogEntry: $s"
}
kpgalligan
10/31/2019, 2:58 PMkpgalligan
10/31/2019, 2:58 PMlet logEngine = LogEngine()
logEngine.log(entry: LogEntry(s: "Hey we're loggin'"))
kpgalligan
10/31/2019, 2:59 PMkpgalligan
10/31/2019, 2:59 PMlog called in main true
Logging: LogEntry: Hey we're loggin', is in main thread false, am I frozen? false
Kris Wong
10/31/2019, 3:00 PMkpgalligan
10/31/2019, 3:00 PMval buffer:MemoryMappedRingBuffer
to be lazy, so you don’t start one per thread, but the rest of the lazy things are just noise.kpgalligan
10/31/2019, 3:00 PMKris Wong
10/31/2019, 3:01 PMkpgalligan
10/31/2019, 3:01 PMkpgalligan
10/31/2019, 3:01 PMkpgalligan
10/31/2019, 3:01 PMkpgalligan
10/31/2019, 3:01 PMKris Wong
10/31/2019, 3:02 PMkpgalligan
10/31/2019, 3:02 PMKris Wong
10/31/2019, 3:03 PMkpgalligan
10/31/2019, 3:03 PMkpgalligan
10/31/2019, 3:05 PMKris Wong
10/31/2019, 3:08 PMKris Wong
10/31/2019, 3:22 PMkpgalligan
10/31/2019, 3:22 PMKris Wong
10/31/2019, 3:33 PMkpgalligan
10/31/2019, 3:35 PMKris Wong
10/31/2019, 3:35 PMkpgalligan
10/31/2019, 3:36 PMkpgalligan
10/31/2019, 3:37 PMKris Wong
10/31/2019, 3:37 PMkpgalligan
10/31/2019, 3:38 PMKris Wong
10/31/2019, 3:39 PMkpgalligan
10/31/2019, 3:40 PMkpgalligan
10/31/2019, 3:40 PMkpgalligan
10/31/2019, 3:41 PMKris Wong
10/31/2019, 3:41 PMKris Wong
10/31/2019, 3:42 PMKris Wong
10/31/2019, 3:43 PMkpgalligan
10/31/2019, 3:47 PMKris Wong
10/31/2019, 3:48 PM