5
5
import java .io .InputStream ;
6
6
import java .net .InetAddress ;
7
7
import java .util .concurrent .TimeUnit ;
8
- import java .util .concurrent .locks .Lock ;
9
- import java .util .concurrent .locks .ReentrantLock ;
8
+ import java .util .concurrent .atomic .AtomicBoolean ;
10
9
11
10
import com .google .common .io .ByteStreams ;
12
11
import io .grpc .CallOptions ;
@@ -71,21 +70,19 @@ public void close() {
71
70
}
72
71
73
72
private static class CallProxy <ReqT , RespT > {
74
- final RequestProxy serverCallListener ;
75
- final ResponseProxy clientCallListener ;
73
+ final ClientProxy clientProxy ;
74
+ final ServerProxy serverProxy ;
76
75
77
76
CallProxy (ServerCall <ReqT , RespT > serverCall , ClientCall <ReqT , RespT > clientCall ) {
78
- serverCallListener = new RequestProxy (clientCall );
79
- clientCallListener = new ResponseProxy (serverCall );
77
+ clientProxy = new ClientProxy (clientCall );
78
+ serverProxy = new ServerProxy (serverCall );
80
79
}
81
80
82
- private class RequestProxy extends ServerCall .Listener <ReqT > {
83
- private final Lock clientCallLock = new ReentrantLock ();
81
+ private class ClientProxy extends ServerCall .Listener <ReqT > {
84
82
private final ClientCall <ReqT , ?> clientCall ;
85
- // Hold 'this' lock when accessing
86
- private boolean needToRequest ;
83
+ private final AtomicBoolean needToRequest = new AtomicBoolean (false );
87
84
88
- RequestProxy (ClientCall <ReqT , ?> clientCall ) {
85
+ ClientProxy (ClientCall <ReqT , ?> clientCall ) {
89
86
this .clientCall = clientCall ;
90
87
}
91
88
@@ -102,47 +99,34 @@ public void onHalfClose() {
102
99
@ Override
103
100
public void onMessage (ReqT message ) {
104
101
clientCall .sendMessage (message );
105
- clientCallLock .lock ();
106
- try {
107
- if (clientCall .isReady ()) {
108
- clientCallListener .serverCall .request (1 );
109
- } else {
110
- // The outgoing call is not ready for more requests. Stop requesting additional data and
111
- // wait for it to catch up.
112
- needToRequest = true ;
113
- }
114
- } finally {
115
- clientCallLock .unlock ();
102
+ if (clientCall .isReady ()) {
103
+ serverProxy .serverCall .request (1 );
104
+ } else {
105
+ // The outgoing call is not ready for more requests. Stop requesting additional data and
106
+ // wait for it to catch up.
107
+ needToRequest .set (true );
116
108
}
117
109
}
118
110
119
111
@ Override
120
112
public void onReady () {
121
- clientCallListener .onServerReady ();
113
+ serverProxy .onServerReady ();
122
114
}
123
115
124
116
// Called from ResponseProxy, which is a different thread than the ServerCall.Listener
125
117
// callbacks.
126
118
void onClientReady () {
127
- clientCallLock .lock ();
128
- try {
129
- if (needToRequest ) {
130
- clientCallListener .serverCall .request (1 );
131
- needToRequest = false ;
132
- }
133
- } finally {
134
- clientCallLock .unlock ();
119
+ if (needToRequest .compareAndSet (true , false )) {
120
+ serverProxy .serverCall .request (1 );
135
121
}
136
122
}
137
123
}
138
124
139
- private class ResponseProxy extends ClientCall .Listener <RespT > {
140
- private final Lock serverCallLock = new ReentrantLock ();
125
+ private class ServerProxy extends ClientCall .Listener <RespT > {
141
126
private final ServerCall <?, RespT > serverCall ;
142
- // Hold 'this' lock when accessing
143
- private boolean needToRequest ;
127
+ private final AtomicBoolean needToRequest = new AtomicBoolean (false );
144
128
145
- ResponseProxy (ServerCall <?, RespT > serverCall ) {
129
+ ServerProxy (ServerCall <?, RespT > serverCall ) {
146
130
this .serverCall = serverCall ;
147
131
}
148
132
@@ -159,36 +143,25 @@ public void onHeaders(Metadata headers) {
159
143
@ Override
160
144
public void onMessage (RespT message ) {
161
145
serverCall .sendMessage (message );
162
- serverCallLock .lock ();
163
- try {
164
- if (serverCall .isReady ()) {
165
- serverCallListener .clientCall .request (1 );
166
- } else {
167
- // The incoming call is not ready for more responses. Stop requesting additional data
168
- // and wait for it to catch up.
169
- needToRequest = true ;
170
- }
171
- } finally {
172
- serverCallLock .unlock ();
146
+ if (serverCall .isReady ()) {
147
+ clientProxy .clientCall .request (1 );
148
+ } else {
149
+ // The incoming call is not ready for more responses. Stop requesting additional data
150
+ // and wait for it to catch up.
151
+ needToRequest .set (true );
173
152
}
174
153
}
175
154
176
155
@ Override
177
156
public void onReady () {
178
- serverCallListener .onClientReady ();
157
+ clientProxy .onClientReady ();
179
158
}
180
159
181
160
// Called from RequestProxy, which is a different thread than the ClientCall.Listener
182
161
// callbacks.
183
162
void onServerReady () {
184
- serverCallLock .lock ();
185
- try {
186
- if (needToRequest ) {
187
- serverCallListener .clientCall .request (1 );
188
- needToRequest = false ;
189
- }
190
- } finally {
191
- serverCallLock .unlock ();
163
+ if (needToRequest .compareAndSet (true , false )) {
164
+ clientProxy .clientCall .request (1 );
192
165
}
193
166
}
194
167
}
@@ -199,10 +172,10 @@ private class ProxyHandler<ReqT, RespT> implements ServerCallHandler<ReqT, RespT
199
172
public ServerCall .Listener <ReqT > startCall (ServerCall <ReqT , RespT > serverCall , Metadata metadata ) {
200
173
ClientCall <ReqT , RespT > clientCall = target .newCall (serverCall .getMethodDescriptor (), CallOptions .DEFAULT );
201
174
CallProxy <ReqT , RespT > proxy = new CallProxy <>(serverCall , clientCall );
202
- clientCall .start (proxy .clientCallListener , metadata );
203
- serverCall .request (1 );
175
+ clientCall .start (proxy .serverProxy , metadata );
204
176
clientCall .request (1 );
205
- return proxy .serverCallListener ;
177
+ serverCall .request (1 );
178
+ return proxy .clientProxy ;
206
179
}
207
180
}
208
181
0 commit comments