Thread-safety for the registry
This commit is contained in:
parent
3586140622
commit
cb828352cc
|
@ -1,4 +1,4 @@
|
||||||
import macros, tables
|
import locks, macros, tables
|
||||||
from options import LogLevel
|
from options import LogLevel
|
||||||
|
|
||||||
type
|
type
|
||||||
|
@ -16,31 +16,45 @@ type
|
||||||
topicStatesTable*: Table[string, ptr Topic]
|
topicStatesTable*: Table[string, ptr Topic]
|
||||||
|
|
||||||
var
|
var
|
||||||
gActiveLogLevel: LogLevel
|
registryLock: Lock
|
||||||
gTotalEnabledTopics: int
|
gActiveLogLevel {.guard: registryLock.}: LogLevel
|
||||||
gTotalRequiredTopics: int
|
gTotalEnabledTopics {.guard: registryLock.}: int
|
||||||
gTopicStates = initTable[string, ptr Topic]()
|
gTotalRequiredTopics {.guard: registryLock.}: int
|
||||||
|
gTopicStates {.guard: registryLock.} = initTable[string, ptr Topic]()
|
||||||
|
mainThreadId = getThreadId()
|
||||||
|
|
||||||
|
initLock(registryLock)
|
||||||
|
|
||||||
|
template lockRegistry(body: untyped) =
|
||||||
|
when compileOption("threads"):
|
||||||
|
withLock registryLock: body
|
||||||
|
else:
|
||||||
|
body
|
||||||
|
|
||||||
proc setLogLevel*(lvl: LogLevel) =
|
proc setLogLevel*(lvl: LogLevel) =
|
||||||
|
lockRegistry:
|
||||||
gActiveLogLevel = lvl
|
gActiveLogLevel = lvl
|
||||||
|
|
||||||
proc clearTopicsRegistry* =
|
proc clearTopicsRegistry* =
|
||||||
|
lockRegistry:
|
||||||
gTotalEnabledTopics = 0
|
gTotalEnabledTopics = 0
|
||||||
gTotalRequiredTopics = 0
|
gTotalRequiredTopics = 0
|
||||||
for val in gTopicStates.values:
|
for val in gTopicStates.values:
|
||||||
val.state = Normal
|
val.state = Normal
|
||||||
|
|
||||||
iterator topicStates*: (string, TopicState) =
|
|
||||||
for name, topic in gTopicStates:
|
|
||||||
yield (name, topic.state)
|
|
||||||
|
|
||||||
proc registerTopic*(name: string, topic: ptr Topic): ptr Topic =
|
proc registerTopic*(name: string, topic: ptr Topic): ptr Topic =
|
||||||
|
# As long as sequences are thread-local, modifying the `gTopicStates`
|
||||||
|
# sequence must be done only from the main thread:
|
||||||
|
doAssert getThreadId() == mainThreadId
|
||||||
|
|
||||||
|
lockRegistry:
|
||||||
gTopicStates[name] = topic
|
gTopicStates[name] = topic
|
||||||
return topic
|
return topic
|
||||||
|
|
||||||
proc setTopicState*(name: string,
|
proc setTopicState*(name: string,
|
||||||
newState: TopicState,
|
newState: TopicState,
|
||||||
logLevel = LogLevel.NONE): bool =
|
logLevel = LogLevel.NONE): bool =
|
||||||
|
lockRegistry:
|
||||||
if not gTopicStates.hasKey(name):
|
if not gTopicStates.hasKey(name):
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
@ -63,6 +77,7 @@ proc setTopicState*(name: string,
|
||||||
|
|
||||||
proc topicsMatch*(logStmtLevel: LogLevel,
|
proc topicsMatch*(logStmtLevel: LogLevel,
|
||||||
logStmtTopics: openarray[ptr Topic]): bool =
|
logStmtTopics: openarray[ptr Topic]): bool =
|
||||||
|
lockRegistry:
|
||||||
var
|
var
|
||||||
hasEnabledTopics = gTotalEnabledTopics > 0
|
hasEnabledTopics = gTotalEnabledTopics > 0
|
||||||
enabledTopicsMatch = false
|
enabledTopicsMatch = false
|
||||||
|
@ -88,5 +103,6 @@ proc topicsMatch*(logStmtLevel: LogLevel,
|
||||||
return normalTopicsMatch
|
return normalTopicsMatch
|
||||||
|
|
||||||
proc getTopicState*(topic: string): ptr Topic =
|
proc getTopicState*(topic: string): ptr Topic =
|
||||||
|
lockRegistry:
|
||||||
return gTopicStates.getOrDefault(topic)
|
return gTopicStates.getOrDefault(topic)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue