1 /*
2  * Copyright (C) 2013, 2014 Brett Wooldridge
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package com.zaxxer.hikari.util;
18
19 import java.sql.SQLException;
20 import java.sql.SQLTransientException;
21 import java.util.concurrent.Semaphore;
22
23 /**
24  * This class implements a lock that can be used to suspend and resume the pool.  It
25  * also provides a faux implementation that is used when the feature is disabled that
26  * hopefully gets fully "optimized away" by the JIT.
27  *
28  * @author Brett Wooldridge
29  */

30 public class SuspendResumeLock
31 {
32    public static final SuspendResumeLock FAUX_LOCK = new SuspendResumeLock(false) {
33       @Override
34       public void acquire() {}
35
36       @Override
37       public void release() {}
38
39       @Override
40       public void suspend() {}
41
42       @Override
43       public void resume() {}
44    };
45
46    private static final int MAX_PERMITS = 10000;
47    private final Semaphore acquisitionSemaphore;
48
49    /**
50     * Default constructor
51     */

52    public SuspendResumeLock()
53    {
54       this(true);
55    }
56
57    private SuspendResumeLock(final boolean createSemaphore)
58    {
59       acquisitionSemaphore = (createSemaphore ? new Semaphore(MAX_PERMITS, true) : null);
60    }
61
62    public void acquire() throws SQLException
63    {
64       if (acquisitionSemaphore.tryAcquire()) {
65          return;
66       }
67       else if (Boolean.getBoolean("com.zaxxer.hikari.throwIfSuspended")) {
68          throw new SQLTransientException("The pool is currently suspended and configured to throw exceptions upon acquisition");
69       }
70
71       acquisitionSemaphore.acquireUninterruptibly();
72    }
73
74    public void release()
75    {
76       acquisitionSemaphore.release();
77    }
78
79    public void suspend()
80    {
81       acquisitionSemaphore.acquireUninterruptibly(MAX_PERMITS);
82    }
83
84    public void resume()
85    {
86       acquisitionSemaphore.release(MAX_PERMITS);
87    }
88 }
89