prevent double free when closing capture library

This commit is contained in:
Craig Raw 2025-06-09 14:43:06 +02:00
parent a94380e882
commit 73d4fd5049
2 changed files with 8 additions and 7 deletions

View file

@ -31,7 +31,6 @@ import com.sparrowwallet.sparrow.io.Config;
import com.sparrowwallet.sparrow.io.bbqr.BBQRDecoder;
import com.sparrowwallet.sparrow.io.bbqr.BBQRException;
import com.sparrowwallet.sparrow.wallet.KeystoreController;
import io.reactivex.Observable;
import javafx.application.Platform;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ObjectProperty;
@ -58,7 +57,6 @@ import java.nio.charset.CharsetDecoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@ -203,8 +201,7 @@ public class QRScanDialog extends Dialog<QRScanDialog.Result> {
Platform.runLater(() -> {
webcamResolutionProperty.set(null);
Observable.just(this).delay(500, TimeUnit.MILLISECONDS)
.subscribe(_ -> webcamService.close(), throwable -> log.error("Error closing webcam", throwable));
webcamService.close();
});
});

View file

@ -39,6 +39,7 @@ public class WebcamService extends ScheduledService<Image> {
private final Semaphore taskSemaphore = new Semaphore(1);
private final AtomicBoolean cancelRequested = new AtomicBoolean(false);
private final AtomicBoolean captureClosed = new AtomicBoolean(false);
private List<CaptureDevice> devices;
private List<CaptureDevice> availableDevices;
@ -112,7 +113,7 @@ public class WebcamService extends ScheduledService<Image> {
return new Task<>() {
@Override
protected Image call() throws Exception {
if(cancelRequested.get() || isCancelled()) {
if(cancelRequested.get() || isCancelled() || captureClosed.get()) {
return null;
}
@ -264,9 +265,12 @@ public class WebcamService extends ScheduledService<Image> {
return cancelled;
}
public void close() {
public synchronized void close() {
if(!captureClosed.get()) {
captureClosed.set(true);
capture.close();
}
}
public PropertyLimits getZoomLimits() {
return zoomLimits;