diff options
author | Apollon Oikonomopoulos <apoikos@debian.org> | 2017-09-13 00:26:38 +0300 |
---|---|---|
committer | Apollon Oikonomopoulos <apoikos@debian.org> | 2017-09-13 00:26:38 +0300 |
commit | c123261d8f14b0b5ca2c18e3648b17264f65438f (patch) | |
tree | fa1a49f0258134ff1bd55f44fae128c1dd86f55f /src/main/java/com/zaxxer/hikari/util | |
parent | 3492d46519ea3fe5fa823115df6f8fa9c4c98879 (diff) | |
parent | 808d040ea9d760bf468621984a3f2de865d35e7c (diff) |
Updated version 2.7.1 from 'upstream/2.7.1'
with Debian dir 15a46d9a58caaa2a40674db085e213646be22b07
Diffstat (limited to 'src/main/java/com/zaxxer/hikari/util')
4 files changed, 42 insertions, 223 deletions
diff --git a/src/main/java/com/zaxxer/hikari/util/ConcurrentBag.java b/src/main/java/com/zaxxer/hikari/util/ConcurrentBag.java index ac0ccb1..9822563 100755 --- a/src/main/java/com/zaxxer/hikari/util/ConcurrentBag.java +++ b/src/main/java/com/zaxxer/hikari/util/ConcurrentBag.java @@ -15,20 +15,23 @@ */ package com.zaxxer.hikari.util; +import static java.lang.Thread.yield; +import static java.util.concurrent.TimeUnit.MICROSECONDS; +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static java.util.concurrent.locks.LockSupport.parkNanos; + import static com.zaxxer.hikari.util.ClockSource.currentTime; import static com.zaxxer.hikari.util.ClockSource.elapsedNanos; import static com.zaxxer.hikari.util.ConcurrentBag.IConcurrentBagEntry.STATE_IN_USE; import static com.zaxxer.hikari.util.ConcurrentBag.IConcurrentBagEntry.STATE_NOT_IN_USE; import static com.zaxxer.hikari.util.ConcurrentBag.IConcurrentBagEntry.STATE_REMOVED; import static com.zaxxer.hikari.util.ConcurrentBag.IConcurrentBagEntry.STATE_RESERVED; -import static java.lang.Thread.yield; -import static java.util.concurrent.TimeUnit.NANOSECONDS; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.Future; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -73,7 +76,7 @@ public class ConcurrentBag<T extends IConcurrentBagEntry> implements AutoCloseab private final SynchronousQueue<T> handoffQueue; - public static interface IConcurrentBagEntry + public interface IConcurrentBagEntry { int STATE_NOT_IN_USE = 0; int STATE_IN_USE = 1; @@ -85,9 +88,9 @@ public class ConcurrentBag<T extends IConcurrentBagEntry> implements AutoCloseab int getState(); } - public static interface IBagStateListener + public interface IBagStateListener { - Future<Boolean> addBagItem(int waiting); + void addBagItem(int waiting); } /** @@ -147,7 +150,7 @@ public class ConcurrentBag<T extends IConcurrentBagEntry> implements AutoCloseab } listener.addBagItem(waiting); - + timeout = timeUnit.toNanos(timeout); do { final long start = currentTime(); @@ -179,11 +182,16 @@ public class ConcurrentBag<T extends IConcurrentBagEntry> implements AutoCloseab { bagEntry.setState(STATE_NOT_IN_USE); - while (waiters.get() > 0) { - if (handoffQueue.offer(bagEntry)) { + for (int i = 0; waiters.get() > 0; i++) { + if (bagEntry.getState() != STATE_NOT_IN_USE || handoffQueue.offer(bagEntry)) { return; } - yield(); + else if ((i & 0xff) == 0xff) { + parkNanos(MICROSECONDS.toNanos(10)); + } + else { + yield(); + } } final List<Object> threadLocalList = threadList.get(); @@ -254,7 +262,9 @@ public class ConcurrentBag<T extends IConcurrentBagEntry> implements AutoCloseab */ public List<T> values(final int state) { - return sharedList.stream().filter(e -> e.getState() == state).collect(Collectors.toList()); + final List<T> list = sharedList.stream().filter(e -> e.getState() == state).collect(Collectors.toList()); + Collections.reverse(list); + return list; } /** diff --git a/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java b/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java index 9aa9b6b..b40decf 100644 --- a/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java +++ b/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java @@ -66,12 +66,29 @@ public final class DriverDataSource implements DataSource if (driver == null) { LOGGER.warn("Registered driver with driverClassName={} was not found, trying direct instantiation.", driverClassName); + Class<?> driverClass = null; try { - Class<?> driverClass = this.getClass().getClassLoader().loadClass(driverClassName); - driver = (Driver) driverClass.newInstance(); + driverClass = this.getClass().getClassLoader().loadClass(driverClassName); + LOGGER.debug("Driver class found in the HikariConfig class classloader {}", this.getClass().getClassLoader()); + } catch (ClassNotFoundException e) { + ClassLoader threadContextClassLoader = Thread.currentThread().getContextClassLoader(); + if (threadContextClassLoader != null && threadContextClassLoader != this.getClass().getClassLoader()) { + try { + driverClass = threadContextClassLoader.loadClass(driverClassName); + LOGGER.debug("Driver class found in Thread context class loader {}", threadContextClassLoader); + } catch (ClassNotFoundException e1) { + LOGGER.warn("Failed to load class of driverClassName {} in either of HikariConfig class classloader {} or Thread context classloader {}", driverClassName, this.getClass().getClassLoader(), threadContextClassLoader); + } + } else { + LOGGER.warn("Failed to load class of driverClassName {} in HikariConfig class classloader {}", driverClassName, this.getClass().getClassLoader()); + } } - catch (Exception e) { - LOGGER.warn("Failed to create instance of driver class {}, trying jdbcUrl resolution", driverClassName, e); + if (driverClass != null) { + try { + driver = (Driver) driverClass.newInstance(); + } catch (Exception e) { + LOGGER.warn("Failed to create instance of driver class {}, trying jdbcUrl resolution", driverClassName, e); + } } } } diff --git a/src/main/java/com/zaxxer/hikari/util/QueuedSequenceSynchronizer.java b/src/main/java/com/zaxxer/hikari/util/QueuedSequenceSynchronizer.java deleted file mode 100644 index eac7ec7..0000000 --- a/src/main/java/com/zaxxer/hikari/util/QueuedSequenceSynchronizer.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2015 Brett Wooldridge - * - * 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.zaxxer.hikari.util; - -import java.util.concurrent.atomic.LongAdder; -import java.util.concurrent.locks.AbstractQueuedLongSynchronizer; - -/** - * A specialized wait/notify class useful for resource tracking through the - * use of a monotonically-increasing long sequence. - * <p> - * When a shared resource becomes available the {@link #signal()} method should - * be called unconditionally. - * <p> - * A thread wishing to acquire a shared resource should: <br> - * <ul> - * <li>Obtain the current sequence from the {@link #currentSequence()} method </li> - * <li>Call {@link #waitUntilSequenceExceeded(long, long)} with that sequence. </li> - * <li>Upon receiving a <code>true</code> result from {@link #waitUntilSequenceExceeded(long, long)}, - * the current sequence should again be obtained from the {@link #currentSequence()} method, - * and an attempt to acquire the resource should be made. </li> - * <li>If the shared resource cannot be acquired, the thread should again call - * {@link #waitUntilSequenceExceeded(long, long)} with the previously obtained sequence. </li> - * <li>If <code>false</code> is received from {@link #waitUntilSequenceExceeded(long, long)} - * then a timeout has occurred. </li> - * </ul> - * <p> - * When running on Java 8 and above, this class leverages the fact that when {@link LongAdder} - * is monotonically increasing, and only {@link LongAdder#increment()} and {@link LongAdder#sum()} - * are used, it can be relied on to be Sequentially Consistent. - * - * @see <a href="http://en.wikipedia.org/wiki/Sequential_consistency">Java Spec</a> - * @author Brett Wooldridge - */ -public final class QueuedSequenceSynchronizer -{ - private final Sequence sequence; - private final Synchronizer synchronizer; - - /** - * Default constructor - */ - public QueuedSequenceSynchronizer() - { - this.synchronizer = new Synchronizer(); - this.sequence = Sequence.Factory.create(); - } - - /** - * Signal any waiting threads. - */ - public void signal() - { - synchronizer.releaseShared(1); - } - - /** - * Get the current sequence. - * - * @return the current sequence - */ - public long currentSequence() - { - return sequence.get(); - } - - /** - * Block the current thread until the current sequence exceeds the specified threshold, or - * until the specified timeout is reached. - * - * @param sequence the threshold the sequence must reach before this thread becomes unblocked - * @param nanosTimeout a nanosecond timeout specifying the maximum time to wait - * @return true if the threshold was reached, false if the wait timed out - * @throws InterruptedException if the thread is interrupted while waiting - */ - public boolean waitUntilSequenceExceeded(long sequence, long nanosTimeout) throws InterruptedException - { - return synchronizer.tryAcquireSharedNanos(sequence, nanosTimeout); - } - - /** - * Queries whether any threads are waiting to for the sequence to reach a particular threshold. - * - * @return true if there may be other threads waiting for a sequence threshold to be reached - */ - public boolean hasQueuedThreads() - { - return synchronizer.hasQueuedThreads(); - } - - /** - * Returns an estimate of the number of threads waiting for a sequence threshold to be reached. The - * value is only an estimate because the number of threads may change dynamically while this method - * traverses internal data structures. This method is designed for use in monitoring system state, - * not for synchronization control. - * - * @return the estimated number of threads waiting for a sequence threshold to be reached - */ - public int getQueueLength() - { - return synchronizer.getQueueLength(); - } - - private final class Synchronizer extends AbstractQueuedLongSynchronizer - { - private static final long serialVersionUID = 104753538004341218L; - - /** {@inheritDoc} */ - @Override - protected long tryAcquireShared(final long seq) - { - return sequence.get() - (seq + 1); - } - - /** {@inheritDoc} */ - @Override - protected boolean tryReleaseShared(final long unused) - { - sequence.increment(); - return true; - } - } -} diff --git a/src/main/java/com/zaxxer/hikari/util/Sequence.java b/src/main/java/com/zaxxer/hikari/util/Sequence.java deleted file mode 100644 index b7abd3c..0000000 --- a/src/main/java/com/zaxxer/hikari/util/Sequence.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2015 Brett Wooldridge - * - * 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.zaxxer.hikari.util; - -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.LongAdder; - -/** - * A monotonically increasing long sequence. - * - * @author brettw - */ -@SuppressWarnings("serial") -public interface Sequence -{ - /** - * Increments the current sequence by one. - */ - void increment(); - - /** - * Get the current sequence. - * - * @return the current sequence. - */ - long get(); - - /** - * Factory class used to create a platform-specific ClockSource. - */ - final class Factory - { - public static Sequence create() - { - if (!Boolean.getBoolean("com.zaxxer.hikari.useAtomicLongSequence")) { - return new Java8Sequence(); - } - else { - return new Java7Sequence(); - } - } - } - - final class Java7Sequence extends AtomicLong implements Sequence { - @Override - public void increment() { - this.incrementAndGet(); - } - } - - final class Java8Sequence extends LongAdder implements Sequence { - @Override - public long get() { - return this.sum(); - } - } -} |