17
17
import java .io .DataInput ;
18
18
import java .io .IOException ;
19
19
import java .net .ConnectException ;
20
- import java .net .SocketTimeoutException ;
21
20
import java .net .InetAddress ;
21
+ import java .net .SocketTimeoutException ;
22
22
import java .nio .ByteBuffer ;
23
23
import java .util .*;
24
24
import java .util .Map .Entry ;
25
25
import java .util .concurrent .ConcurrentHashMap ;
26
26
import java .util .concurrent .CopyOnWriteArrayList ;
27
27
import java .util .concurrent .TimeUnit ;
28
28
import java .util .concurrent .atomic .AtomicBoolean ;
29
+ import java .util .concurrent .locks .Lock ;
30
+ import java .util .concurrent .locks .ReentrantLock ;
29
31
import java .util .function .BiConsumer ;
30
32
import java .util .stream .Collectors ;
31
33
35
37
*/
36
38
@ MBean (description ="Server used to accept connections from other servers (or clients) and send data to servers" )
37
39
public abstract class BaseServer implements Closeable , ConnectionListener {
40
+ protected final Lock lock =new ReentrantLock ();
38
41
protected Address local_addr ; // typically the address of the server socket or channel
39
42
protected final List <ConnectionListener > conn_listeners =new CopyOnWriteArrayList <>();
40
43
protected final Map <Address ,Connection > conns =new ConcurrentHashMap <>();
@@ -159,10 +162,13 @@ public void stop() {
159
162
Util .close (reaper );
160
163
reaper =null ;
161
164
162
- synchronized (this ) {
165
+ lock .lock ();
166
+ try {
163
167
for (Connection c : conns .values ())
164
168
Util .close (c );
165
169
conns .clear ();
170
+ } finally {
171
+ lock .unlock ();
166
172
}
167
173
conn_listeners .clear ();
168
174
}
@@ -171,17 +177,29 @@ public void close() throws IOException {
171
177
stop ();
172
178
}
173
179
174
- public synchronized void flush (Address dest ) {
180
+ public void flush (Address dest ) {
175
181
if (dest != null ) {
176
- Connection conn =conns .get (dest );
177
- if (conn != null )
178
- conn .flush ();
182
+ lock .lock ();
183
+ try {
184
+ Connection conn =conns .get (dest );
185
+ if (conn != null )
186
+ conn .flush ();
187
+ }
188
+ finally {
189
+ lock .unlock ();
190
+ }
179
191
}
180
192
}
181
193
182
- public synchronized void flushAll () {
183
- for (Connection c : conns .values ())
184
- c .flush ();
194
+ public void flushAll () {
195
+ lock .lock ();
196
+ try {
197
+ for (Connection c : conns .values ())
198
+ c .flush ();
199
+ }
200
+ finally {
201
+ lock .unlock ();
202
+ }
185
203
}
186
204
187
205
@@ -322,7 +340,8 @@ public Connection getConnection(Address dest) throws Exception {
322
340
if (connected (conn =conns .get (dest )))
323
341
return conn ;
324
342
325
- synchronized (this ) {
343
+ lock .lock ();
344
+ try {
326
345
if (connected (conn =conns .get (dest )))
327
346
return conn ;
328
347
conn =createConnection (dest );
@@ -340,6 +359,8 @@ public Connection getConnection(Address dest) throws Exception {
340
359
removeConnectionIfPresent (dest , conn ); // removes and closes the conn
341
360
throw connect_ex ;
342
361
}
362
+ } finally {
363
+ lock .unlock ();
343
364
}
344
365
return conn ;
345
366
}
@@ -378,17 +399,23 @@ public boolean closeConnection(Address addr, boolean notify) {
378
399
}
379
400
380
401
381
- public synchronized void addConnection (Address peer_addr , Connection conn ) throws Exception {
382
- boolean conn_exists =hasConnection (peer_addr ),
383
- replace =conn_exists && local_addr .compareTo (peer_addr ) < 0 ; // bigger conn wins
402
+ public void addConnection (Address peer_addr , Connection conn ) throws Exception {
403
+ lock .lock ();
404
+ try {
405
+ boolean conn_exists =hasConnection (peer_addr ),
406
+ replace =conn_exists && local_addr .compareTo (peer_addr ) < 0 ; // bigger conn wins
384
407
385
- if (!conn_exists || replace ) {
386
- replaceConnection (peer_addr , conn ); // closes old conn
387
- conn .start ();
408
+ if (!conn_exists || replace ) {
409
+ replaceConnection (peer_addr , conn ); // closes old conn
410
+ conn .start ();
411
+ }
412
+ else {
413
+ log .trace ("%s: rejected connection from %s %s" , local_addr , peer_addr , explanation (conn_exists , replace ));
414
+ Util .close (conn ); // keep our existing conn, reject accept() and close client_sock
415
+ }
388
416
}
389
- else {
390
- log .trace ("%s: rejected connection from %s %s" , local_addr , peer_addr , explanation (conn_exists , replace ));
391
- Util .close (conn ); // keep our existing conn, reject accept() and close client_sock
417
+ finally {
418
+ lock .unlock ();
392
419
}
393
420
}
394
421
@@ -427,11 +454,15 @@ public void removeConnectionIfPresent(Address address, Connection conn) {
427
454
if (address == null || conn == null )
428
455
return ;
429
456
Connection tmp =null ;
430
- synchronized (this ) {
457
+
458
+ lock .lock ();
459
+ try {
431
460
Connection existing =conns .get (address );
432
461
if (conn == existing ) {
433
462
tmp =conns .remove (address );
434
463
}
464
+ } finally {
465
+ lock .unlock ();
435
466
}
436
467
if (tmp != null ) { // Moved conn close outside of sync block (https://issues.redhat.com/browse/JGRP-2053)
437
468
log .trace ("%s: removed connection to %s" , local_addr , address );
@@ -440,9 +471,15 @@ public void removeConnectionIfPresent(Address address, Connection conn) {
440
471
}
441
472
442
473
/** Used only for testing ! */
443
- public synchronized void clearConnections () {
444
- conns .values ().forEach (Util ::close );
445
- conns .clear ();
474
+ public void clearConnections () {
475
+ lock .lock ();
476
+ try {
477
+ conns .values ().forEach (Util ::close );
478
+ conns .clear ();
479
+ }
480
+ finally {
481
+ lock .unlock ();
482
+ }
446
483
}
447
484
448
485
public void forAllConnections (BiConsumer <Address ,Connection > c ) {
@@ -455,9 +492,12 @@ public void retainAll(Collection<Address> current_mbrs) {
455
492
return ;
456
493
457
494
Map <Address ,Connection > copy =null ;
458
- synchronized (this ) {
495
+ lock .lock ();
496
+ try {
459
497
copy =new HashMap <>(conns );
460
498
conns .keySet ().retainAll (current_mbrs );
499
+ } finally {
500
+ lock .unlock ();
461
501
}
462
502
copy .keySet ().removeAll (current_mbrs );
463
503
for (Map .Entry <Address ,Connection > entry : copy .entrySet ())
@@ -599,7 +639,8 @@ public synchronized void stop() {
599
639
600
640
public void run () {
601
641
while (!Thread .currentThread ().isInterrupted ()) {
602
- synchronized (BaseServer .this ) {
642
+ lock .lock ();
643
+ try {
603
644
for (Iterator <Entry <Address ,Connection >> it =conns .entrySet ().iterator ();it .hasNext ();) {
604
645
Entry <Address ,Connection > entry =it .next ();
605
646
Connection c =entry .getValue ();
@@ -608,6 +649,8 @@ public void run() {
608
649
it .remove ();
609
650
}
610
651
}
652
+ } finally {
653
+ lock .unlock ();
611
654
}
612
655
Util .sleep (reaperInterval );
613
656
}
0 commit comments