- Timestamp:
- 2024-07-25T22:54:48+02:00 (10 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadAndZoomHandler.java ¶
r19152 r19153 8 8 import java.util.Collection; 9 9 import java.util.Collections; 10 import java.util.HashMap; 10 11 import java.util.LinkedHashSet; 11 12 import java.util.List; … … 16 17 import java.util.concurrent.TimeUnit; 17 18 import java.util.concurrent.TimeoutException; 19 import java.util.concurrent.locks.ReadWriteLock; 20 import java.util.concurrent.locks.ReentrantReadWriteLock; 18 21 import java.util.stream.Collectors; 19 22 import java.util.stream.Stream; … … 73 76 private static final String SEARCH = "search"; 74 77 78 private static final Map<String, ReadWriteLock> layerLockMap = new HashMap<>(); 79 75 80 // Mandatory arguments 76 81 private double minlat; … … 161 166 private void download() throws RequestHandlerErrorException { 162 167 DownloadOsmTask osmTask = new DownloadOsmTask(); 168 ReadWriteLock lock = null; 169 DownloadParams settings = null; 163 170 try { 164 DownloadParamssettings = getDownloadParams();171 settings = getDownloadParams(); 165 172 166 173 if (command.equals(myCommand)) { … … 168 175 Logging.info("RemoteControl: download forbidden by preferences"); 169 176 } else { 177 // The lock ensures that a download that creates a new layer will finish before 178 // downloads that do not create a new layer. This should be thread-safe. 179 lock = obtainLock(settings); 180 // We need to ensure that we only try to download new areas 170 181 Area toDownload = null; 171 182 if (!settings.isNewLayer()) { … … 179 190 } 180 191 } 192 } catch (InterruptedException ex) { 193 Thread.currentThread().interrupt(); 194 throw new RequestHandlerErrorException(ex); 181 195 } catch (RuntimeException ex) { // NOPMD 182 196 Logging.warn("RemoteControl: Error parsing load_and_zoom remote control request:"); 183 197 Logging.error(ex); 184 198 throw new RequestHandlerErrorException(ex); 199 } finally { 200 releaseLock(settings, lock); 201 } 202 } 203 204 /** 205 * Obtain a lock to ensure that a new layer is created before downloading non-new layers 206 * @param settings The settings with the appropriate layer name; if no layer name is given, we assume that 207 * the caller doesn't care where the data goes. 208 * @return The lock to pass to {@link #releaseLock(DownloadParams, ReadWriteLock)} or {@code null} if no lock is needed. 209 * @throws InterruptedException If the lock could not be obtained. 210 */ 211 private static ReadWriteLock obtainLock(DownloadParams settings) throws InterruptedException { 212 final ReadWriteLock lock; 213 if (settings.isNewLayer() && !Utils.isEmpty(settings.getLayerName())) { 214 synchronized (layerLockMap) { 215 lock = layerLockMap.computeIfAbsent(settings.getLayerName(), k -> new ReentrantReadWriteLock()); 216 lock.writeLock().lock(); 217 } 218 } else { 219 synchronized (layerLockMap) { 220 lock = layerLockMap.get(settings.getLayerName()); 221 } 222 if (lock != null) { 223 lock.readLock().lockInterruptibly(); 224 } 225 } 226 return lock; 227 } 228 229 /** 230 * Release the lock preventing data from being downloaded into an old layer 231 * @param settings The settings with information on the new layer status 232 * @param lock The lock to unlock 233 */ 234 private static void releaseLock(DownloadParams settings, ReadWriteLock lock) { 235 if (lock != null) { 236 if (settings != null && settings.isNewLayer()) { 237 lock.writeLock().unlock(); 238 synchronized (layerLockMap) { 239 layerLockMap.remove(settings.getLayerName()); 240 } 241 } else { 242 lock.readLock().unlock(); 243 } 185 244 } 186 245 } … … 213 272 } 214 273 215 private void performDownload(DownloadOsmTask osmTask, DownloadParams settings) { 274 /** 275 * Perform the actual download; this is synchronized to ensure that we only have one download going on at a time 276 * @param osmTask The task that will show a dialog 277 * @param settings The download settings 278 * @throws RequestHandlerErrorException If there is an issue getting data 279 */ 280 private void performDownload(DownloadOsmTask osmTask, DownloadParams settings) throws RequestHandlerErrorException { 216 281 Future<?> future = MainApplication.worker.submit( 217 282 new PostDownloadHandler(osmTask, osmTask.download(settings, new Bounds(minlat, minlon, maxlat, maxlon), … … 245 310 } 246 311 }); 312 // Don't block forever, but do wait some period of time. 313 try { 314 future.get(OSM_DOWNLOAD_TIMEOUT.get(), TimeUnit.SECONDS); 315 } catch (InterruptedException e) { 316 Thread.currentThread().interrupt(); 317 throw new RequestHandlerErrorException(e); 318 } catch (TimeoutException | ExecutionException e) { 319 throw new RequestHandlerErrorException(e); 320 } 247 321 } 248 322
Note:
See TracChangeset
for help on using the changeset viewer.