Skip to content

Commit 4586073

Browse files
committed
MT hardening FileInfoReader eclipse-equinox#568
The value of the barrier (true/false) was never read. It was only checked for !=null. The value had been read in waitOnSelf() without any multithreading semantics like synchronize/volatile. Instead now we use a thread safe AtomicBoolean. The synchronization blocks are still used for wait()/notifyAll() eclipse-equinox#568
1 parent 65348d6 commit 4586073

File tree

1 file changed

+23
-23
lines changed
  • bundles/org.eclipse.equinox.p2.transport.ecf/src/org/eclipse/equinox/internal/p2/transport/ecf

1 file changed

+23
-23
lines changed

bundles/org.eclipse.equinox.p2.transport.ecf/src/org/eclipse/equinox/internal/p2/transport/ecf/FileInfoReader.java

+23-23
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import java.io.FileNotFoundException;
1515
import java.io.IOException;
1616
import java.net.URI;
17+
import java.util.concurrent.atomic.AtomicBoolean;
1718
import org.eclipse.core.runtime.*;
1819
import org.eclipse.core.runtime.jobs.Job;
1920
import org.eclipse.ecf.core.*;
@@ -34,21 +35,21 @@
3435
* ECF). If such support is added, this class is easily modified.
3536
*/
3637
public class FileInfoReader extends Job implements IRemoteFileSystemListener {
37-
private Exception exception;
38-
private IProgressMonitor theMonitor;
38+
private volatile Exception exception;
39+
private volatile IProgressMonitor theMonitor;
3940
private final int connectionRetryCount;
4041
private final long connectionRetryDelay;
4142
private final IConnectContext connectContext;
42-
final Boolean[] barrier = new Boolean[1];
43-
private IRemoteFile[] remoteFiles;
44-
private IRemoteFileSystemRequest browseRequest;
43+
private final AtomicBoolean barrierReached = new AtomicBoolean();
44+
private volatile IRemoteFile[] remoteFiles;
45+
private volatile IRemoteFileSystemRequest browseRequest;
4546

4647
@Override
4748
protected IStatus run(IProgressMonitor monitor) {
48-
synchronized (barrier) {
49-
while (barrier[0] == null) {
49+
synchronized (barrierReached) {
50+
while (!barrierReached.get()) {
5051
try {
51-
barrier.wait(1000);
52+
barrierReached.wait(1000);
5253
if (theMonitor.isCanceled() && browseRequest != null)
5354
browseRequest.cancel();
5455
} catch (InterruptedException e) {
@@ -60,14 +61,13 @@ protected IStatus run(IProgressMonitor monitor) {
6061
}
6162

6263
/**
63-
* Waits until request is processed (barrier[0] is non null).
64-
* This is a bit of a hack, as it would be better if the ECFBrowser worked in similar fashion to
65-
* file transfer were a custom job can be supplied.
66-
* TODO: log an issue for ECF.
64+
* Waits until request is processed (barrierReached.get()). This is a bit of a
65+
* hack, as it would be better if the ECFBrowser worked in similar fashion to
66+
* file transfer were a custom job can be supplied. TODO: log an issue for ECF.
6767
*/
6868
private void waitOnSelf() {
6969
schedule();
70-
while (barrier[0] == null) {
70+
while (!barrierReached.get()) {
7171
boolean logged = false;
7272
try {
7373
join();
@@ -84,7 +84,6 @@ private void waitOnSelf() {
8484
*/
8585
public FileInfoReader(IConnectContext aConnectContext) {
8686
super(Messages.repo_loading); // job label - TODO: this is a bad label
87-
barrier[0] = null;
8887
// Hide this job.
8988
setSystem(true);
9089
setUser(false);
@@ -136,23 +135,24 @@ public long getLastModified(URI location, IProgressMonitor monitor) throws Authe
136135
public void handleRemoteFileEvent(IRemoteFileSystemEvent event) {
137136
exception = event.getException();
138137
if (exception != null) {
139-
synchronized (barrier) {
140-
barrier[0] = Boolean.TRUE;
141-
barrier.notify();
138+
synchronized (barrierReached) {
139+
barrierReached.set(true);
140+
barrierReached.notifyAll();
142141
}
143142
} else if (event instanceof IRemoteFileSystemBrowseEvent) {
144143
IRemoteFileSystemBrowseEvent fsbe = (IRemoteFileSystemBrowseEvent) event;
145144
remoteFiles = fsbe.getRemoteFiles();
146145
if (theMonitor != null)
147146
theMonitor.worked(1);
148-
synchronized (barrier) {
149-
barrier[0] = Boolean.TRUE;
150-
barrier.notify();
147+
synchronized (barrierReached) {
148+
barrierReached.set(true);
149+
barrierReached.notifyAll();
151150
}
152151
} else {
153-
synchronized (barrier) {
154-
barrier[0] = Boolean.FALSE; // ended by unknown reason
155-
barrier.notify();
152+
synchronized (barrierReached) {
153+
// ended by unknown reason, but ended
154+
barrierReached.set(true);
155+
barrierReached.notifyAll();
156156
}
157157
}
158158
}

0 commit comments

Comments
 (0)