Skip to content

Commit daf075c

Browse files
ahus1belaban
authored andcommitted
- Avoiding synchronized in BaseServer as it would pin the threads when using virtual threads (JGRP-2864)
- Replaced 'synchronized' with locks where feasible
1 parent 3f845c1 commit daf075c

File tree

2 files changed

+69
-26
lines changed

2 files changed

+69
-26
lines changed

bin/jgroups.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ FLAGS="-server -Xmx1G -Xms500m -XX:+HeapDumpOnOutOfMemoryError -Djava.net.prefer
5656
# DUMP_VTHREADS=-Djdk.trackAllThreads=true
5757

5858
# Dump when virtual threads are pinned on a carrier thread
59-
# FLAGS="$FLAGS Djdk.tracePinnedThreads=full"
59+
# FLAGS="$FLAGS -Djdk.tracePinnedThreads=full"
6060

6161
java $GC $DUMP_VTHREADS $Z1 -cp $CP $SSL_FLAGS $DEBUG $LOG $JG_FLAGS $FLAGS $JMX $JMC $*
6262

src/org/jgroups/blocks/cs/BaseServer.java

Lines changed: 68 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@
1717
import java.io.DataInput;
1818
import java.io.IOException;
1919
import java.net.ConnectException;
20-
import java.net.SocketTimeoutException;
2120
import java.net.InetAddress;
21+
import java.net.SocketTimeoutException;
2222
import java.nio.ByteBuffer;
2323
import java.util.*;
2424
import java.util.Map.Entry;
2525
import java.util.concurrent.ConcurrentHashMap;
2626
import java.util.concurrent.CopyOnWriteArrayList;
2727
import java.util.concurrent.TimeUnit;
2828
import java.util.concurrent.atomic.AtomicBoolean;
29+
import java.util.concurrent.locks.Lock;
30+
import java.util.concurrent.locks.ReentrantLock;
2931
import java.util.function.BiConsumer;
3032
import java.util.stream.Collectors;
3133

@@ -35,6 +37,7 @@
3537
*/
3638
@MBean(description="Server used to accept connections from other servers (or clients) and send data to servers")
3739
public abstract class BaseServer implements Closeable, ConnectionListener {
40+
protected final Lock lock=new ReentrantLock();
3841
protected Address local_addr; // typically the address of the server socket or channel
3942
protected final List<ConnectionListener> conn_listeners=new CopyOnWriteArrayList<>();
4043
protected final Map<Address,Connection> conns=new ConcurrentHashMap<>();
@@ -159,10 +162,13 @@ public void stop() {
159162
Util.close(reaper);
160163
reaper=null;
161164

162-
synchronized(this) {
165+
lock.lock();
166+
try {
163167
for(Connection c: conns.values())
164168
Util.close(c);
165169
conns.clear();
170+
} finally {
171+
lock.unlock();
166172
}
167173
conn_listeners.clear();
168174
}
@@ -171,17 +177,29 @@ public void close() throws IOException {
171177
stop();
172178
}
173179

174-
public synchronized void flush(Address dest) {
180+
public void flush(Address dest) {
175181
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+
}
179191
}
180192
}
181193

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+
}
185203
}
186204

187205

@@ -322,7 +340,8 @@ public Connection getConnection(Address dest) throws Exception {
322340
if(connected(conn=conns.get(dest)))
323341
return conn;
324342

325-
synchronized(this) {
343+
lock.lock();
344+
try {
326345
if(connected(conn=conns.get(dest)))
327346
return conn;
328347
conn=createConnection(dest);
@@ -340,6 +359,8 @@ public Connection getConnection(Address dest) throws Exception {
340359
removeConnectionIfPresent(dest, conn); // removes and closes the conn
341360
throw connect_ex;
342361
}
362+
} finally {
363+
lock.unlock();
343364
}
344365
return conn;
345366
}
@@ -378,17 +399,23 @@ public boolean closeConnection(Address addr, boolean notify) {
378399
}
379400

380401

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
384407

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+
}
388416
}
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();
392419
}
393420
}
394421

@@ -427,11 +454,15 @@ public void removeConnectionIfPresent(Address address, Connection conn) {
427454
if(address == null || conn == null)
428455
return;
429456
Connection tmp=null;
430-
synchronized(this) {
457+
458+
lock.lock();
459+
try {
431460
Connection existing=conns.get(address);
432461
if(conn == existing) {
433462
tmp=conns.remove(address);
434463
}
464+
} finally {
465+
lock.unlock();
435466
}
436467
if(tmp != null) { // Moved conn close outside of sync block (https://issues.redhat.com/browse/JGRP-2053)
437468
log.trace("%s: removed connection to %s", local_addr, address);
@@ -440,9 +471,15 @@ public void removeConnectionIfPresent(Address address, Connection conn) {
440471
}
441472

442473
/** 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+
}
446483
}
447484

448485
public void forAllConnections(BiConsumer<Address,Connection> c) {
@@ -455,9 +492,12 @@ public void retainAll(Collection<Address> current_mbrs) {
455492
return;
456493

457494
Map<Address,Connection> copy=null;
458-
synchronized(this) {
495+
lock.lock();
496+
try {
459497
copy=new HashMap<>(conns);
460498
conns.keySet().retainAll(current_mbrs);
499+
} finally {
500+
lock.unlock();
461501
}
462502
copy.keySet().removeAll(current_mbrs);
463503
for(Map.Entry<Address,Connection> entry: copy.entrySet())
@@ -599,7 +639,8 @@ public synchronized void stop() {
599639

600640
public void run() {
601641
while(!Thread.currentThread().isInterrupted()) {
602-
synchronized(BaseServer.this) {
642+
lock.lock();
643+
try {
603644
for(Iterator<Entry<Address,Connection>> it=conns.entrySet().iterator();it.hasNext();) {
604645
Entry<Address,Connection> entry=it.next();
605646
Connection c=entry.getValue();
@@ -608,6 +649,8 @@ public void run() {
608649
it.remove();
609650
}
610651
}
652+
} finally {
653+
lock.unlock();
611654
}
612655
Util.sleep(reaperInterval);
613656
}

0 commit comments

Comments
 (0)