Ver código fonte

genericize atomic config changes

tags/v2.10.0-rc1
Shivaram Lingamneni 2 anos atrás
pai
commit
c603d41d08
3 arquivos alterados com 35 adições e 9 exclusões
  1. 1
    6
      irc/getters.go
  2. 2
    3
      irc/server.go
  3. 32
    0
      irc/utils/config.go

+ 1
- 6
irc/getters.go Ver arquivo

@@ -7,7 +7,6 @@ import (
7 7
 	"net"
8 8
 	"sync/atomic"
9 9
 	"time"
10
-	"unsafe"
11 10
 
12 11
 	"github.com/ergochat/ergo/irc/caps"
13 12
 	"github.com/ergochat/ergo/irc/languages"
@@ -16,11 +15,7 @@ import (
16 15
 )
17 16
 
18 17
 func (server *Server) Config() (config *Config) {
19
-	return (*Config)(atomic.LoadPointer(&server.config))
20
-}
21
-
22
-func (server *Server) SetConfig(config *Config) {
23
-	atomic.StorePointer(&server.config, unsafe.Pointer(config))
18
+	return server.config.Get()
24 19
 }
25 20
 
26 21
 func (server *Server) ChannelRegistrationEnabled() bool {

+ 2
- 3
irc/server.go Ver arquivo

@@ -17,7 +17,6 @@ import (
17 17
 	"sync"
18 18
 	"syscall"
19 19
 	"time"
20
-	"unsafe"
21 20
 
22 21
 	"github.com/ergochat/irc-go/ircfmt"
23 22
 	"github.com/okzk/sdnotify"
@@ -66,7 +65,7 @@ type Server struct {
66 65
 	channels          ChannelManager
67 66
 	channelRegistry   ChannelRegistry
68 67
 	clients           ClientManager
69
-	config            unsafe.Pointer
68
+	config            utils.ConfigStore[Config]
70 69
 	configFilename    string
71 70
 	connectionLimiter connection_limits.Limiter
72 71
 	ctime             time.Time
@@ -704,7 +703,7 @@ func (server *Server) applyConfig(config *Config) (err error) {
704 703
 	config.Server.Cloaks.SetSecret(LoadCloakSecret(server.store))
705 704
 
706 705
 	// activate the new config
707
-	server.SetConfig(config)
706
+	server.config.Set(config)
708 707
 
709 708
 	// load [dk]-lines, registered users and channels, etc.
710 709
 	if initial {

+ 32
- 0
irc/utils/config.go Ver arquivo

@@ -0,0 +1,32 @@
1
+// Copyright (c) 2022 Shivaram Lingamneni
2
+// released under the MIT license
3
+
4
+package utils
5
+
6
+import (
7
+	"sync/atomic"
8
+	"unsafe"
9
+)
10
+
11
+/*
12
+This can be used to implement the following pattern:
13
+
14
+1. Load and munge a config (this can be arbitrarily expensive)
15
+2. Use Set() to install the config
16
+3. Use Get() to access the config
17
+4. As long as any individual config is not modified (by any goroutine)
18
+   after the initial call to Set(), this is free of data races, and Get()
19
+   is extremely cheap (on amd64 it compiles down to plain MOV instructions).
20
+*/
21
+
22
+type ConfigStore[T any] struct {
23
+	ptr unsafe.Pointer
24
+}
25
+
26
+func (c *ConfigStore[T]) Get() *T {
27
+	return (*T)(atomic.LoadPointer(&c.ptr))
28
+}
29
+
30
+func (c *ConfigStore[T]) Set(ptr *T) {
31
+	atomic.StorePointer(&c.ptr, unsafe.Pointer(ptr))
32
+}

Carregando…
Cancelar
Salvar