@@ -30,14 +30,14 @@ type Receiver struct {
30
30
NewOut chan <- NewOutChans
31
31
32
32
newOut <- chan NewOutChans
33
+ outLock * sync.RWMutex
33
34
out chan pgproto3.BackendMessage
34
35
outSync * misc.Cond
35
36
detaching chan struct {}
36
37
37
38
closed chan struct {}
38
39
closeFrontend func ()
39
40
receive func () (pgproto3.BackendMessage , error )
40
- forwarderChan chan pgproto3.BackendMessage
41
41
42
42
dropRFQ bool
43
43
dropRFQChan chan struct {}
@@ -55,49 +55,39 @@ func Launch(
55
55
r := & Receiver {
56
56
NewOut : newOut ,
57
57
newOut : newOut ,
58
- forwarderChan : make ( chan pgproto3. BackendMessage , 1 ) ,
58
+ outLock : & sync. RWMutex {} ,
59
59
dropRFQChan : unblockedChannel ,
60
60
dropRFQLock : new (sync.Mutex ),
61
61
closeFrontend : closeFrontend ,
62
62
closed : closed ,
63
63
receive : receive ,
64
64
}
65
65
66
- go r .forwarder ()
66
+ go r .outManager ()
67
67
go r .receiver ()
68
68
69
69
return r
70
70
}
71
71
72
- func (r * Receiver ) forwarder () {
72
+ func (r * Receiver ) outManager () {
73
73
defer misc .Recover ()
74
74
defer r .closeFrontend ()
75
75
defer func () {
76
+ r .outLock .Lock ()
77
+ defer r .outLock .Unlock ()
76
78
if r .out != nil {
77
79
close (r .out )
78
80
}
79
81
r .outSync .SignalLocked ()
82
+ r .out = nil
83
+ r .outSync = nil
84
+ r .detaching = nil
80
85
}()
81
86
82
87
for {
83
88
select {
84
- case msg , ok := <- r .forwarderChan :
85
- if ! ok {
86
- return
87
- }
88
-
89
- if r .out == nil {
90
- log .Println ("client detached unexpectedly. cannot send message to client!" , misc .Marshal (msg ))
91
- return
92
- }
93
-
94
- select {
95
- case r .out <- msg :
96
- case <- r .detaching :
97
- goto detaching
98
- }
99
-
100
89
case newChan := <- r .newOut :
90
+ r .outLock .Lock ()
101
91
if r .out != nil {
102
92
close (r .out )
103
93
}
@@ -106,31 +96,28 @@ func (r *Receiver) forwarder() {
106
96
r .detaching = newChan .Detaching
107
97
108
98
r .outSync .SignalLocked ()
99
+ r .outLock .Unlock ()
109
100
110
101
case <- r .detaching :
111
- goto detaching
102
+ r .outLock .Lock ()
103
+ if r .out != nil {
104
+ close (r .out )
105
+ }
106
+ r .outSync .SignalLocked ()
107
+ r .out = nil
108
+ r .outSync = nil
109
+ r .detaching = nil
110
+ r .outLock .Unlock ()
112
111
113
112
case <- r .closed :
114
113
return
115
114
}
116
-
117
- continue
118
-
119
- detaching:
120
- if r .out != nil {
121
- close (r .out )
122
- }
123
- r .outSync .SignalLocked ()
124
- r .out = nil
125
- r .outSync = nil
126
- r .detaching = nil
127
115
}
128
116
}
129
117
130
118
func (r * Receiver ) receiver () {
131
119
defer misc .Recover ()
132
120
defer r .closeFrontend ()
133
- defer close (r .forwarderChan )
134
121
135
122
for {
136
123
bmsg , err := r .receive ()
@@ -148,21 +135,32 @@ func (r *Receiver) receiver() {
148
135
continue
149
136
}
150
137
151
- // log.Println("f-msg-1", misc.Marshal(bmsg))
152
- r .outSync .L .Lock ()
153
- select {
154
- case r .forwarderChan <- bmsg :
155
- r .outSync .WaitAndUnlock ()
156
- case <- r .closed :
138
+ closed := r .Send (bmsg )
139
+ if closed {
157
140
return
158
141
}
159
142
}
160
143
}
161
144
162
- func (r * Receiver ) Send (bmsg pgproto3.BackendMessage ) {
145
+ func (r * Receiver ) Send (bmsg pgproto3.BackendMessage ) bool {
146
+ r .outLock .RLock ()
147
+ defer r .outLock .RUnlock ()
148
+
149
+ if r .out == nil {
150
+ log .Println ("client detached unexpectedly. cannot send message to client!" , misc .Marshal (bmsg ))
151
+ return true
152
+ }
153
+
154
+ // log.Println("f-msg-1", misc.Marshal(bmsg))
163
155
r .outSync .L .Lock ()
164
- r .forwarderChan <- bmsg
165
- r .outSync .WaitAndUnlock ()
156
+ select {
157
+ case r .out <- bmsg :
158
+ r .outSync .WaitAndUnlock ()
159
+ case <- r .closed :
160
+ return true
161
+ }
162
+
163
+ return false
166
164
}
167
165
168
166
// when proxying application_name, we will get an RFQ that the
0 commit comments