Skip to content

Commit b6c2721

Browse files
committed
Replaced synchronized with locks (https://issues.redhat.com/browse/JGRP-2863)
1 parent daf075c commit b6c2721

File tree

3 files changed

+78
-81
lines changed

3 files changed

+78
-81
lines changed

src/org/jgroups/Membership.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ public Membership add(Collection<Address> v) {
8989
return this;
9090
}
9191

92-
9392
/**
9493
* Removes a member from the membership. If this member doesn't exist, no action will be
9594
* performed on the existing membership
@@ -104,7 +103,6 @@ public Membership remove(Address old_member) {
104103
return this;
105104
}
106105

107-
108106
/**
109107
* Removes all the members contained in v from this membership
110108
* @param v a list of all the members to be removed
@@ -127,7 +125,6 @@ public Membership retainAll(Collection<Address> v) {
127125
return this;
128126
}
129127

130-
131128
/**
132129
* Removes all the members from this membership
133130
*/
@@ -257,6 +254,12 @@ public boolean isCoord(Address mbr) {
257254
}
258255
}
259256

257+
public Address nextCoord() {
258+
synchronized(members) {
259+
return members.size() > 1? members.get(1) : null;
260+
}
261+
}
262+
260263
/**
261264
* Returns the members to the left of mbr
262265
* @param mbr The member whose neighbor to the left should be returned

src/org/jgroups/protocols/pbcast/GMS.java

Lines changed: 62 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public class GMS extends Protocol implements DiagnosticsHandler.ProbeHandler {
110110
protected int num_views;
111111
protected BoundedList<String> prev_views; // History of the last N views
112112
protected GmsImpl impl;
113-
protected final Lock impl_lock=new ReentrantLock(); // synchronizes event entry into impl
113+
protected final Lock lock=new ReentrantLock();
114114
protected final Map<String,GmsImpl> impls=new HashMap<>(3);
115115

116116
protected Merger merger; // handles merges
@@ -309,14 +309,14 @@ public List<Integer> providedDownServices() {
309309
}
310310

311311
public void setImpl(GmsImpl new_impl) {
312-
impl_lock.lock();
312+
lock.lock();
313313
try {
314314
if(impl == new_impl)
315315
return;
316316
impl=new_impl;
317317
}
318318
finally {
319-
impl_lock.unlock();
319+
lock.unlock();
320320
}
321321
}
322322

@@ -433,7 +433,8 @@ public void cancelMerge() {
433433
* {@code suspected_mbrs} removed and {@code joiners} added.
434434
*/
435435
public View getNextView(Collection<Address> joiners, Collection<Address> leavers, Collection<Address> suspected_mbrs) {
436-
synchronized(members) {
436+
lock.lock();
437+
try {
437438
ViewId view_id=view != null? view.getViewId() : null;
438439
if(view_id == null) {
439440
log.error(Util.getMessage("ViewidIsNull"));
@@ -461,6 +462,9 @@ public View getNextView(Collection<Address> joiners, Collection<Address> leavers
461462
suspected_mbrs.stream().filter(addr -> !leaving.contains(addr)).forEach(leaving::add);
462463
return v;
463464
}
465+
finally {
466+
lock.unlock();
467+
}
464468
}
465469

466470
/** Computes the regular membership */
@@ -602,42 +606,43 @@ public void installView(View new_view) {
602606
* Sets the new view and sends a VIEW_CHANGE event up and down the stack. If the view is a MergeView (subclass
603607
* of View), then digest will be non-null and has to be set before installing the view.
604608
*/
605-
public synchronized void installView(View new_view, Digest digest) {
606-
ViewId vid=new_view.getViewId();
609+
public void installView(View new_view, Digest digest) {
610+
Event view_event;
611+
ViewId vid=new_view.getViewId();
607612
List<Address> mbrs=new_view.getMembers();
608-
ltime=Math.max(vid.getId(), ltime); // compute the logical time, regardless of whether the view is accepted
613+
boolean am_i_coord;
614+
lock.lock();
615+
try {
616+
ltime=Math.max(vid.getId(), ltime); // compute the logical time, regardless of whether the view is accepted
609617

610-
// Discards view with id lower than or equal to our own. Will be installed without check if it is the first view
611-
if(view != null && vid.compareToIDs(view.getViewId()) <= 0)
612-
return;
618+
// Discards view with id lower than or equal to our own. Will be installed without check if it is the first view
619+
if(view != null && vid.compareToIDs(view.getViewId()) <= 0)
620+
return;
613621

614-
/* Check for self-inclusion: if I'm not part of the new membership, I just discard it.
622+
/* Check for self-inclusion: if I'm not part of the new membership, I just discard it.
615623
This ensures that messages sent in view V1 are only received by members of V1 */
616-
if(!mbrs.contains(local_addr)) {
617-
if(log_view_warnings)
618-
log.warn("%s: not member of view %s; discarding it", local_addr, new_view.getViewId());
619-
return;
620-
}
624+
if(!mbrs.contains(local_addr)) {
625+
if(log_view_warnings)
626+
log.warn("%s: not member of view %s; discarding it", local_addr, new_view.getViewId());
627+
return;
628+
}
621629

622-
if(digest != null) {
623-
if(new_view instanceof MergeView)
624-
mergeDigest(digest);
625-
else
626-
setDigest(digest);
627-
}
630+
if(digest != null) {
631+
if(new_view instanceof MergeView)
632+
mergeDigest(digest);
633+
else
634+
setDigest(digest);
635+
}
628636

629-
if(log.isDebugEnabled()) {
630-
Address[][] diff=View.diff(view, new_view);
631-
log.debug("%s: installing view %s %s", local_addr, new_view,
632-
print_view_details? View.printDiff(diff) : "");
633-
}
637+
if(log.isDebugEnabled()) {
638+
Address[][] diff=View.diff(view, new_view);
639+
log.debug("%s: installing view %s %s", local_addr, new_view,
640+
print_view_details? View.printDiff(diff) : "");
641+
}
634642

635-
Event view_event;
636-
boolean was_coord, is_coord;
637-
synchronized(members) {
638-
was_coord=view != null && Objects.equals(local_addr, view.getCoord());
643+
boolean was_coord=view != null && Objects.equals(local_addr, view.getCoord());
639644
view=new_view;
640-
is_coord=Objects.equals(local_addr, view.getCoord());
645+
boolean is_coord=Objects.equals(local_addr, view.getCoord());
641646
view_event=new Event(Event.VIEW_CHANGE, new_view);
642647

643648
// Set the membership. Take into account joining members
@@ -647,12 +652,8 @@ public synchronized void installView(View new_view, Digest digest) {
647652
joining.removeAll(mbrs); // remove all members in mbrs from joining
648653
// remove all elements from 'leaving' that are not in 'mbrs'
649654
leaving.retainAll(mbrs);
650-
651-
tmp_members.add(joining); // add members that haven't yet shown up in the membership
652-
tmp_members.remove(leaving); // remove members that haven't yet been removed from the membership
655+
tmp_members.add(joining).remove(leaving);
653656
suspected_mbrs.retainAll(mbrs);
654-
655-
// add to prev_members
656657
mbrs.stream().filter(addr -> !prev_members.contains(addr)).forEach(addr -> prev_members.add(addr));
657658
}
658659

@@ -664,6 +665,15 @@ public synchronized void installView(View new_view, Digest digest) {
664665
if(was_coord || impl instanceof ClientGmsImpl)
665666
becomeParticipant();
666667
}
668+
ack_collector.retainAll(new_view.getMembers());
669+
if(stats) {
670+
num_views++;
671+
prev_views.add(Util.utcNow() + ": " + new_view);
672+
}
673+
am_i_coord=Objects.equals(local_addr, new_view.getCoord());
674+
}
675+
finally {
676+
lock.unlock();
667677
}
668678

669679
// - Changed order of passing view up and down (https://issues.redhat.com/browse/JGRP-347)
@@ -672,45 +682,31 @@ public synchronized void installView(View new_view, Digest digest) {
672682
down_prot.down(view_event); // needed e.g. by failure detector or UDP
673683
up_prot.up(view_event);
674684

675-
List<Address> tmp_mbrs=new_view.getMembers();
676-
ack_collector.retainAll(tmp_mbrs);
677-
678-
if(new_view instanceof MergeView) {
679-
// Everybody except the merge leader cancels the merge, otherwise - if UNICAST3.loopback is true - we'd
680-
// interrupt our own thread which will fail code that later sends a message before returning!
681-
// Note that the merge leader does cancel the merge later, after having installed the MergeView
682-
// (in Merger.handleMergeView() in the finally clause)
683-
if(!Objects.equals(local_addr, new_view.getCoord()))
684-
merger.forceCancelMerge();
685-
}
686-
687-
if(stats) {
688-
num_views++;
689-
prev_views.add(Util.utcNow() + ": " + new_view);
690-
}
685+
// Everybody except the merge leader cancels the merge, otherwise - if UNICAST3.loopback is true - we'd
686+
// interrupt our own thread which will fail code that later sends a message before returning!
687+
// Note that the merge leader does cancel the merge later, after having installed the MergeView
688+
// (in Merger.handleMergeView() in the finally clause)
689+
if(new_view instanceof MergeView && !am_i_coord)
690+
merger.forceCancelMerge();
691691
}
692692

693693
protected Address getCoord() {
694-
impl_lock.lock();
694+
lock.lock();
695695
try {
696696
return isCoord()? determineNextCoordinator() : determineCoordinator();
697697
}
698698
finally {
699-
impl_lock.unlock();
699+
lock.unlock();
700700
}
701701
}
702702

703703
protected Address determineCoordinator() {
704-
synchronized(members) {
705-
return members.getFirst();
706-
}
704+
return members.getFirst();
707705
}
708706

709707
/** Returns the second-in-line */
710708
protected Address determineNextCoordinator() {
711-
synchronized(members) {
712-
return members.size() > 1? members.elementAt(1) : null;
713-
}
709+
return members.nextCoord();
714710
}
715711

716712
protected static View createDeltaView(final View current_view, final View next_view) {
@@ -720,36 +716,35 @@ protected static View createDeltaView(final View current_view, final View next_v
720716
return new DeltaView(next_view_id, current_view_id, diff[1], diff[0]);
721717
}
722718

723-
724719
/** Checks whether the potential_new_coord would be the new coordinator (2nd in line) */
725720
protected boolean wouldBeNewCoordinator(Address potential_new_coord) {
726721
if(potential_new_coord == null) return false;
727-
synchronized(members) {
722+
lock.lock();
723+
try {
728724
if(members.size() < 2) return false;
729725
Address new_coord=members.elementAt(1); // member at 2nd place
730726
return Objects.equals(new_coord, potential_new_coord);
731727
}
728+
finally {
729+
lock.unlock();
730+
}
732731
}
733732

734-
735733
/** Send down a SET_DIGEST event */
736734
public void setDigest(Digest d) {
737735
down_prot.down(new Event(Event.SET_DIGEST, d));
738736
}
739737

740-
741738
/** Send down a MERGE_DIGEST event */
742739
public void mergeDigest(Digest d) {
743740
down_prot.down(new Event(Event.MERGE_DIGEST,d));
744741
}
745742

746-
747743
/** Grabs the current digest from NAKACK{2} */
748744
public Digest getDigest() {
749745
return (Digest)down_prot.down(Event.GET_DIGEST_EVT);
750746
}
751747

752-
753748
public Object up(Event evt) {
754749
switch(evt.getType()) {
755750
case Event.SUSPECT:

tests/junit-functional/org/jgroups/tests/MembershipTest.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ void setUp() {
3434
m1=new Membership();
3535
}
3636

37-
3837
public void testConstructor() {
3938
v1=Arrays.asList(a1, a2, a3);
4039
m2=new Membership(v1);
@@ -44,7 +43,6 @@ public void testConstructor() {
4443
assert m2.contains(a3);
4544
}
4645

47-
4846
public void testClone() {
4947
v1=Arrays.asList(a1, a2, a3);
5048
m2=new Membership(v1);
@@ -56,8 +54,6 @@ public void testClone() {
5654
assert m2.contains(a2);
5755
}
5856

59-
60-
6157
public void testCopy() {
6258
v1=Arrays.asList(a1, a2, a3);
6359
m2=new Membership(v1);
@@ -69,8 +65,6 @@ public void testCopy() {
6965
assert m2.contains(a2);
7066
}
7167

72-
73-
7468
public void testAdd() {
7569
m1.add(a1, a2, a3);
7670
assert m1.size() == 2;
@@ -79,8 +73,6 @@ public void testAdd() {
7973
assert m1.contains(a3);
8074
}
8175

82-
83-
8476
public void testAddVector() {
8577
v1=Arrays.asList(a1, a2, a3);
8678
m1.add(v1);
@@ -89,7 +81,6 @@ public void testAddVector() {
8981
assert m1.contains(a2);
9082
}
9183

92-
9384
public void testAddVectorDupl() {
9485
v1=Arrays.asList(a1, a2, a3, a4, a5);
9586
m1.add(a5, a1).add(v1);
@@ -100,13 +91,11 @@ public void testAddVectorDupl() {
10091
assert m1.contains(a5);
10192
}
10293

103-
10494
public void testRemove() {
10595
m1.add(a1, a2, a3, a4, a5).remove(a2);
10696
assert m1.size() == 3;
10797
}
10898

109-
11099
public void testGetMembers() {
111100
testAdd();
112101
List<Address> v=m1.getMembers();
@@ -138,6 +127,16 @@ public void testIsCoord() {
138127
assert !coord;
139128
}
140129

130+
public void testNextCoord() {
131+
m1.add(a1,a2);
132+
assert m1.isCoord(a1);
133+
Address tmp=m1.nextCoord();
134+
assert a2.equals(tmp);
135+
m1.remove(a2);
136+
tmp=m1.nextCoord();
137+
assert tmp == null;
138+
}
139+
141140
public void testGetNext() {
142141
Address next=m1.getNext(null);
143142
assert next == null;

0 commit comments

Comments
 (0)