49
49
* @see Connection
50
50
*/
51
51
public abstract class AMQChannel extends ShutdownNotifierComponent {
52
+ /**
53
+ * Private; used instead of synchronizing on the channel itself,
54
+ * so that clients can themselves use the channel to synchronize
55
+ * on.
56
+ */
57
+ public final Object _channelMutex = new Object ();
58
+
52
59
/** The connection this channel is associated with. */
53
60
public final AMQConnection _connection ;
54
61
@@ -156,19 +163,23 @@ public void handleCompleteInboundCommand(AMQCommand command) throws IOException
156
163
}
157
164
}
158
165
159
- public synchronized void enqueueRpc (RpcContinuation k )
166
+ public void enqueueRpc (RpcContinuation k )
160
167
{
161
- if (_activeRpc != null ) {
162
- throw new IllegalStateException ("cannot execute more than one synchronous AMQP command at a time" );
168
+ synchronized (_channelMutex ) {
169
+ if (_activeRpc != null ) {
170
+ throw new IllegalStateException ("cannot execute more than one synchronous AMQP command at a time" );
171
+ }
172
+ _activeRpc = k ;
163
173
}
164
- _activeRpc = k ;
165
174
}
166
175
167
- public synchronized RpcContinuation nextOutstandingRpc ()
176
+ public RpcContinuation nextOutstandingRpc ()
168
177
{
169
- RpcContinuation result = _activeRpc ;
170
- _activeRpc = null ;
171
- return result ;
178
+ synchronized (_channelMutex ) {
179
+ RpcContinuation result = _activeRpc ;
180
+ _activeRpc = null ;
181
+ return result ;
182
+ }
172
183
}
173
184
174
185
public void ensureIsOpen ()
@@ -198,18 +209,22 @@ public AMQCommand rpc(Method m)
198
209
return k .getReply ();
199
210
}
200
211
201
- public synchronized void rpc (Method m , RpcContinuation k )
212
+ public void rpc (Method m , RpcContinuation k )
202
213
throws IOException
203
214
{
204
- ensureIsOpen ();
205
- quiescingRpc (m , k );
215
+ synchronized (_channelMutex ) {
216
+ ensureIsOpen ();
217
+ quiescingRpc (m , k );
218
+ }
206
219
}
207
220
208
- public synchronized void quiescingRpc (Method m , RpcContinuation k )
221
+ public void quiescingRpc (Method m , RpcContinuation k )
209
222
throws IOException
210
223
{
211
- enqueueRpc (k );
212
- quiescingTransmit (m );
224
+ synchronized (_channelMutex ) {
225
+ enqueueRpc (k );
226
+ quiescingTransmit (m );
227
+ }
213
228
}
214
229
215
230
/**
@@ -237,13 +252,13 @@ public void processShutdownSignal(ShutdownSignalException signal,
237
252
boolean ignoreClosed ,
238
253
boolean notifyRpc ) {
239
254
try {
240
- synchronized (this ) {
255
+ synchronized (_channelMutex ) {
241
256
if (!ignoreClosed )
242
257
ensureIsOpen (); // invariant: we should never be shut down more than once per instance
243
258
if (isOpen ())
244
259
_shutdownCause = signal ;
245
260
246
- notifyAll ();
261
+ _channelMutex . notifyAll ();
247
262
}
248
263
} finally {
249
264
if (notifyRpc )
@@ -258,33 +273,41 @@ public void notifyOutstandingRpc(ShutdownSignalException signal) {
258
273
}
259
274
}
260
275
261
- public synchronized void transmit (Method m ) throws IOException {
262
- transmit (new AMQCommand (m ));
276
+ public void transmit (Method m ) throws IOException {
277
+ synchronized (_channelMutex ) {
278
+ transmit (new AMQCommand (m ));
279
+ }
263
280
}
264
281
265
- public synchronized void transmit (AMQCommand c ) throws IOException {
266
- ensureIsOpen ();
267
- quiescingTransmit (c );
282
+ public void transmit (AMQCommand c ) throws IOException {
283
+ synchronized (_channelMutex ) {
284
+ ensureIsOpen ();
285
+ quiescingTransmit (c );
286
+ }
268
287
}
269
288
270
- public synchronized void quiescingTransmit (Method m ) throws IOException {
271
- quiescingTransmit (new AMQCommand (m ));
289
+ public void quiescingTransmit (Method m ) throws IOException {
290
+ synchronized (_channelMutex ) {
291
+ quiescingTransmit (new AMQCommand (m ));
292
+ }
272
293
}
273
294
274
- public synchronized void quiescingTransmit (AMQCommand c ) throws IOException {
275
- if (c .getMethod ().hasContent ()) {
276
- while (_blockContent ) {
277
- try {
278
- wait ();
279
- } catch (InterruptedException e ) {}
280
-
281
- // This is to catch a situation when the thread wakes up during
282
- // shutdown. Currently, no command that has content is allowed
283
- // to send anything in a closing state.
284
- ensureIsOpen ();
295
+ public void quiescingTransmit (AMQCommand c ) throws IOException {
296
+ synchronized (_channelMutex ) {
297
+ if (c .getMethod ().hasContent ()) {
298
+ while (_blockContent ) {
299
+ try {
300
+ _channelMutex .wait ();
301
+ } catch (InterruptedException e ) {}
302
+
303
+ // This is to catch a situation when the thread wakes up during
304
+ // shutdown. Currently, no command that has content is allowed
305
+ // to send anything in a closing state.
306
+ ensureIsOpen ();
307
+ }
285
308
}
309
+ c .transmit (this );
286
310
}
287
- c .transmit (this );
288
311
}
289
312
290
313
public AMQConnection getAMQConnection () {
0 commit comments