/******************************************************************************* * Copyright 2013 SAP AG * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package com.sap.core.odata.testutil.helper; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.sap.core.odata.testutil.TestUtilRuntimeException; /** * Interprocess synchronization to enable parallel test executions. * * @author SAP AG */ public class ProcessLocker { @SuppressWarnings("unused") private static final Logger log = LoggerFactory.getLogger(ProcessLocker.class); //Acquire public static void crossProcessLockAcquire(final Class<?> c, final long waitMS) { RandomAccessFile randomAccessFile = null; if ((fileLock == null) && (c != null) && (waitMS > 0)) { try { final long dropDeadTime = System.currentTimeMillis() + waitMS; final File file = new File(lockTempDir, c.getName() + ".lock"); randomAccessFile = new RandomAccessFile(file, "rw"); final FileChannel fileChannel = randomAccessFile.getChannel(); while (System.currentTimeMillis() < dropDeadTime) { fileLock = fileChannel.tryLock(); if (fileLock != null) { break; } Thread.sleep(250); // 4 attempts/sec } } catch (final IOException e) { throw new TestUtilRuntimeException(e); } catch (final InterruptedException e) { throw new TestUtilRuntimeException(e); } } if (fileLock == null) { throw new TestUtilRuntimeException("timeout after " + waitMS); } } // Release public static void crossProcessLockRelease() { if (fileLock != null) { try { fileLock.release(); fileLock = null; } catch (final IOException e) { throw new TestUtilRuntimeException(e); } } } private static File lockTempDir = new File(System.getProperty("java.io.tmpdir") + File.separator + "locks"); static { lockTempDir.mkdirs(); } private static FileLock fileLock = null; static { Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { crossProcessLockRelease(); } }); } }