@@ -18,6 +18,11 @@ var noDeadline = time.Time{}
18
18
// Global atomic counter for connection IDs
19
19
var connIDCounter uint64
20
20
21
+ // atomicNetConn is a wrapper to ensure consistent typing in atomic.Value
22
+ type atomicNetConn struct {
23
+ conn net.Conn
24
+ }
25
+
21
26
// generateConnID generates a fast unique identifier for a connection with zero allocations
22
27
func generateConnID () uint64 {
23
28
return atomic .AddUint64 (& connIDCounter , 1 )
@@ -27,8 +32,8 @@ type Conn struct {
27
32
usedAt int64 // atomic
28
33
29
34
// Lock-free netConn access using atomic.Value
30
- // Contains net.Conn , accessed atomically for better performance
31
- netConnAtomic atomic.Value // stores net.Conn
35
+ // Contains *atomicNetConn wrapper , accessed atomically for better performance
36
+ netConnAtomic atomic.Value // stores *atomicNetConn
32
37
33
38
rd * proto.Reader
34
39
bw * bufio.Writer
@@ -74,8 +79,8 @@ func NewConn(netConn net.Conn) *Conn {
74
79
id : generateConnID (), // Generate unique ID for this connection
75
80
}
76
81
77
- // Store netConn atomically for lock-free access
78
- cn .netConnAtomic .Store (netConn )
82
+ // Store netConn atomically for lock-free access using wrapper
83
+ cn .netConnAtomic .Store (& atomicNetConn { conn : netConn } )
79
84
80
85
// Initialize atomic handoff state
81
86
atomic .StoreInt32 (& cn .usableAtomic , 0 ) // false initially, set to true after initialization
@@ -103,16 +108,18 @@ func (cn *Conn) SetUsedAt(tm time.Time) {
103
108
// getNetConn returns the current network connection using atomic load (lock-free).
104
109
// This is the fast path for accessing netConn without mutex overhead.
105
110
func (cn * Conn ) getNetConn () net.Conn {
106
- if conn := cn .netConnAtomic .Load (); conn != nil {
107
- return conn .(net.Conn )
111
+ if v := cn .netConnAtomic .Load (); v != nil {
112
+ if wrapper , ok := v .(* atomicNetConn ); ok {
113
+ return wrapper .conn
114
+ }
108
115
}
109
116
return nil
110
117
}
111
118
112
119
// setNetConn stores the network connection atomically (lock-free).
113
120
// This is used for the fast path of connection replacement.
114
121
func (cn * Conn ) setNetConn (netConn net.Conn ) {
115
- cn .netConnAtomic .Store (netConn )
122
+ cn .netConnAtomic .Store (& atomicNetConn { conn : netConn } )
116
123
}
117
124
118
125
// Lock-free helper methods for handoff state management
@@ -311,14 +318,13 @@ func (cn *Conn) SetInitConnFunc(fn func(context.Context, *Conn) error) {
311
318
// ExecuteInitConn runs the stored connection initialization function if available.
312
319
func (cn * Conn ) ExecuteInitConn (ctx context.Context ) error {
313
320
if cn .initConnFunc != nil {
314
- err := cn .initConnFunc (ctx , cn )
315
- if err == nil {
316
- cn .Inited = true
317
- cn .setUsable (true ) // Use atomic operation
321
+ if err := cn .initConnFunc (ctx , cn ); err != nil {
322
+ return err
318
323
}
319
- return err
324
+ cn .Inited = true
325
+ cn .setUsable (true ) // Use atomic operation
320
326
}
321
- return nil
327
+ return fmt . Errorf ( "redis: no initConnFunc set for connection %d" , cn . GetID ())
322
328
}
323
329
324
330
func (cn * Conn ) SetNetConn (netConn net.Conn ) {
0 commit comments