• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

evolvedbinary / elemental / 982

29 Apr 2025 08:34PM UTC coverage: 56.409% (+0.007%) from 56.402%
982

push

circleci

adamretter
[feature] Improve README.md badges

28451 of 55847 branches covered (50.94%)

Branch coverage included in aggregate %.

77468 of 131924 relevant lines covered (58.72%)

0.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

30.91
/exist-core/src/main/java/org/exist/storage/lock/ManagedLock.java
1
/*
2
 * Elemental
3
 * Copyright (C) 2024, Evolved Binary Ltd
4
 *
5
 * admin@evolvedbinary.com
6
 * https://www.evolvedbinary.com | https://www.elemental.xyz
7
 *
8
 * Use of this software is governed by the Business Source License 1.1
9
 * included in the LICENSE file and at www.mariadb.com/bsl11.
10
 *
11
 * Change Date: 2028-04-27
12
 *
13
 * On the date above, in accordance with the Business Source License, use
14
 * of this software will be governed by the Apache License, Version 2.0.
15
 *
16
 * Additional Use Grant: Production use of the Licensed Work for a permitted
17
 * purpose. A Permitted Purpose is any purpose other than a Competing Use.
18
 * A Competing Use means making the Software available to others in a commercial
19
 * product or service that: substitutes for the Software; substitutes for any
20
 * other product or service we offer using the Software that exists as of the
21
 * date we make the Software available; or offers the same or substantially
22
 * similar functionality as the Software.
23
 */
24
package org.exist.storage.lock;
25

26
import org.exist.util.LockException;
27

28
import java.util.concurrent.locks.ReentrantLock;
29

30
/**
31
 * Provides a simple wrapper around a Lock
32
 * so that it may be used in a try-with-resources
33
 * statement
34
 *
35
 * @author <a href="mailto:adam.retter@googlemail.com">Adam Retter</a>
36
 */
37
public class ManagedLock<T> implements AutoCloseable {
38
    protected final T lock;
39
    private final Runnable closer;
40
    protected volatile boolean closed = false;
1✔
41

42
    ManagedLock(final T lock, final Runnable closer) {
1✔
43
        this.lock = lock;
1✔
44
        this.closer = closer;
1✔
45
    }
1✔
46

47
    /**
48
     * Acquires and manages a lock with a specific mode
49
     *
50
     * @param lock The lock to call {@link Lock#acquire(Lock.LockMode)} on
51
     * @param mode the mode of the lock
52
     *
53
     * @return A managed lock which will be released with {@link #close()}
54
     *
55
     * @throws LockException if a lock error occurs
56
     */
57
    public static ManagedLock<Lock> acquire(final Lock lock, final Lock.LockMode mode) throws LockException {
58
        if(!lock.acquire(mode)) {
×
59
            throw new LockException("Unable to acquire lock");
×
60
        }
61
        return new ManagedLock<>(lock, () -> lock.release(mode));
×
62
    }
63

64
    /**
65
     * Acquires and manages a lock with a specific mode
66
     *
67
     * @param lock The lock to call {@link Lock#acquire(Lock.LockMode)} on
68
     * @param mode the mode of the lock
69
     * @param type the type of the lock
70
     *
71
     * @return A managed lock which will be released with {@link #close()}
72
     * @throws LockException if a lock error occurs
73
     */
74
    public static ManagedLock<Lock> acquire(final Lock lock, final Lock.LockMode mode, final Lock.LockType type) throws LockException {
75
        if(!lock.acquire(mode)) {
×
76
            throw new LockException("Unable to acquire lock: " + type);
×
77
        }
78
        return new ManagedLock<>(lock, () -> lock.release(mode));
×
79
    }
80

81
    /**
82
     * Attempts to acquire and manage a lock with a specific mode
83
     *
84
     * @param lock The lock to call {@link Lock#attempt(Lock.LockMode)} on
85
     * @param mode the mode of the lock
86
     *
87
     * @return A managed lock which will be released with {@link #close()}
88
     * @throws LockException if a lock error occurs
89
     */
90
    public static ManagedLock<Lock> attempt(final Lock lock, final Lock.LockMode mode) throws LockException {
91
        if(!lock.attempt(mode)) {
×
92
            throw new LockException("Unable to attempt to acquire lock");
×
93
        }
94
        return new ManagedLock<>(lock, () -> lock.release(mode));
×
95
    }
96

97
    /**
98
     * Acquires and manages a lock with a specific mode
99
     *
100
     * @param lock The lock to call {@link java.util.concurrent.locks.Lock#lock()} on
101
     * @param mode the mode of the lock
102
     *
103
     * @return A managed lock which will be released with {@link #close()}
104
     */
105
    public static ManagedLock<java.util.concurrent.locks.ReadWriteLock> acquire(final java.util.concurrent.locks.ReadWriteLock lock, final Lock.LockMode mode) {
106
        final java.util.concurrent.locks.Lock modeLock = switch (mode) {
1!
107
            case READ_LOCK -> lock.readLock();
1✔
108
            case WRITE_LOCK -> lock.writeLock();
1✔
109
            default -> throw new IllegalArgumentException();
×
110
        };
111

112
        modeLock.lock();
1✔
113
        return new ManagedLock<>(lock, modeLock::unlock);
1✔
114
    }
115

116
    /**
117
     * Attempts to acquire and manage a lock with a specific mode
118
     *
119
     * @param lock The lock to call {@link java.util.concurrent.locks.Lock#tryLock()} on
120
     * @param mode the mode of the lock
121
     *
122
     * @return A managed lock which will be released with {@link #close()}
123
     * @throws LockException if a lock error occurs
124
     */
125
    public static ManagedLock<java.util.concurrent.locks.ReadWriteLock> attempt(final java.util.concurrent.locks.ReadWriteLock lock, final Lock.LockMode mode) throws LockException {
126
        final java.util.concurrent.locks.Lock modeLock = switch (mode) {
×
127
            case READ_LOCK -> lock.readLock();
×
128
            case WRITE_LOCK -> lock.writeLock();
×
129
            default -> throw new IllegalArgumentException();
×
130
        };
131

132
        if(!modeLock.tryLock()) {
×
133
            throw new LockException("Unable to attempt to acquire lock");
×
134
        }
135
        return new ManagedLock<>(lock, modeLock::unlock);
×
136
    }
137

138
    /**
139
     * Acquires and manages a lock
140
     *
141
     * @param lock The lock to call {@link java.util.concurrent.locks.Lock#lock()} on
142
     *
143
     * @return A managed lock which will be released with {@link #close()}
144
     */
145
    public static ManagedLock<ReentrantLock> acquire(final ReentrantLock lock) {
146
        lock.lock();
×
147
        return new ManagedLock<>(lock, lock::unlock);
×
148
    }
149

150
    /**
151
     * Attempts to acquire and manage a lock
152
     *
153
     * @param lock The lock to call {@link java.util.concurrent.locks.Lock#tryLock()} on
154
     *
155
     * @return A managed lock which will be released with {@link #close()}
156
     * @throws LockException if a lock error occurs
157
     */
158
    public static ManagedLock<ReentrantLock> attempt(final ReentrantLock lock) throws LockException {
159
        if(!lock.tryLock()) {
×
160
            throw new LockException("Unable to attempt to acquire lock");
×
161
        }
162
        return new ManagedLock<>(lock, lock::unlock);
×
163
    }
164

165
    /**
166
     * Determines if the lock has already been released
167
     *
168
     * @return true if the lock has already been released
169
     */
170
    boolean isReleased() {
171
        return closed;
×
172
    }
173

174
    /**
175
     * Releases the lock
176
     */
177
    @Override
178
    public void close() {
179
        if (!closed) {
1!
180
            closer.run();
1✔
181
        }
182
        this.closed = true;
1✔
183
    }
1✔
184
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc