Skip to content

Commit

Permalink
Merge branch '2.18' into interncache-lock
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Mar 28, 2024
2 parents e68a512 + 695ca3f commit 59b3089
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 11 deletions.
3 changes: 2 additions & 1 deletion release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ a pure JSON library.

2.18.0 (not yet released)

-
#1252: `ThreadLocalBufferManager` replace synchronized with `ReentrantLock`
(contributed by @pjfanning)

2.17.1 (not yet released)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,10 +364,9 @@ public static CharsToNameCanonicalizer createRoot(TokenStreamFactory owner, int
* read-only copy of parent's data, but when changes are needed, a
* copy will be created.
*<p>
* Note: while this method is synchronized, it is generally not
* safe to both use makeChild/mergeChild, AND to use instance
* actively. Instead, a separate 'root' instance should be used
* on which only makeChild/mergeChild are called, but instance itself
* Note: It is generally not safe to both use makeChild/mergeChild, AND to
* use instance actively. Instead, a separate 'root' instance should be
* used on which only makeChild/mergeChild are called, but instance itself
* is not used as a symbol table.
*
* @return Actual canonicalizer instance that can be used by a parser
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

/**
* For issue [jackson-core#400] We keep a separate Set of all SoftReferences to BufferRecyclers
Expand All @@ -23,7 +24,7 @@ class ThreadLocalBufferManager
* A lock to make sure releaseBuffers is only executed by one thread at a time
* since it iterates over and modifies the allSoftBufRecyclers.
*/
private final Object RELEASE_LOCK = new Object();
private final ReentrantLock RELEASE_LOCK = new ReentrantLock();

/**
* A set of all SoftReferences to all BufferRecyclers to be able to release them on shutdown.
Expand Down Expand Up @@ -64,17 +65,20 @@ public static ThreadLocalBufferManager instance() {
* It will clear all bufRecyclers from the SoftRefs and release all SoftRefs itself from our set.
*/
public int releaseBuffers() {
synchronized (RELEASE_LOCK) {
int count = 0;
int count = 0;
RELEASE_LOCK.lock();
try {
// does this need to be in sync block too? Looping over Map definitely has to but...
removeSoftRefsClearedByGc(); // make sure the refQueue is empty
for (SoftReference<BufferRecycler> ref : _trackedRecyclers.keySet()) {
ref.clear(); // possibly already cleared by gc, nothing happens in that case
++count;
}
_trackedRecyclers.clear(); //release cleared SoftRefs
return count;
} finally {
RELEASE_LOCK.unlock();
}
return count;
}

public SoftReference<BufferRecycler> wrapAndTrack(BufferRecycler br) {
Expand All @@ -95,8 +99,7 @@ public SoftReference<BufferRecycler> wrapAndTrack(BufferRecycler br) {

/**
* Remove cleared (inactive) SoftRefs from our set. Gc may have cleared one or more,
* and made them inactive. We minimize contention by keeping synchronized sections short:
* the poll/remove methods
* and made them inactive.
*/
private void removeSoftRefsClearedByGc() {
SoftReference<?> clearedSoftRef;
Expand Down

0 comments on commit 59b3089

Please sign in to comment.