Skip to content

Commit

Permalink
AFCore: Revert limit to 1MB; allocate buffers on-the-fly if exceeded
Browse files Browse the repository at this point in the history
The limit to how large datagram can be seems to have no feasibly low
limit (25MB datagrams have been reported to work). This imposes a
challenge on caching/reuse strategies for direct byte buffers (a shared,
reusable pool that is not thread-specific could be an alternative, but
comes at the cost of complexity).

At the cost of performance, revert the per-thread limit to 1MB, and
return newly allocated direct byte buffers instead of cached ones
whenever the limit is exceeded.

Users of such unexpectedly large datagrams could either still force a
higher (or unbounded) limit via the system property
"org.newsclub.net.unix.thread-local-buffer.max-capacity", or better,
use direct byte buffers in the calling code, obsoleting the need to
use this cache in the first place.

#118
  • Loading branch information
kohlschuetter committed Oct 4, 2022
1 parent a068ed9 commit 34b5a5f
Showing 1 changed file with 15 additions and 3 deletions.
18 changes: 15 additions & 3 deletions junixsocket-common/src/main/java/org/newsclub/net/unix/AFCore.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ class AFCore extends CleanableState {

private static final int TL_BUFFER_MIN_CAPACITY = 8192; // 8 kb per thread
private static final int TL_BUFFER_MAX_CAPACITY = Integer.parseInt(System.getProperty(
PROP_TL_BUFFER_MAX_CAPACITY, Integer.toString(8 * 1024 * 1024))); // 8 MB per thread,
// realistic upper limit
PROP_TL_BUFFER_MAX_CAPACITY, Integer.toString(1 * 1024 * 1024))); // 1 MB per thread

private final AtomicBoolean closed = new AtomicBoolean(false);

Expand Down Expand Up @@ -209,9 +208,22 @@ int write(ByteBuffer src, SocketAddress target, int options) throws IOException
return written;
}

/**
* Returns a per-thread reusable byte buffer for a given capacity.
*
* If a thread-local buffer currently uses a smaller capacity, the buffer is replaced by a larger
* one. If the capacity exceeds a configurable maximum, a new direct buffer is allocated but not
* cached (i.e., the previously cached one is kept but not immediately returned to the caller).
*
* @param capacity The desired capacity.
* @return A byte buffer satisfying the requested capacity.
*/
ByteBuffer getThreadLocalDirectByteBuffer(int capacity) {
if (capacity > TL_BUFFER_MAX_CAPACITY && TL_BUFFER_MAX_CAPACITY > 0) {
capacity = TL_BUFFER_MAX_CAPACITY;
// Capacity exceeds configurable maximum limit;
// allocate but do not cache direct buffer.
// This may incur a performance penalty at the cost of correctness when using such capacities.
return ByteBuffer.allocateDirect(capacity);
}
if (capacity < TL_BUFFER_MIN_CAPACITY) {
capacity = TL_BUFFER_MIN_CAPACITY;
Expand Down

0 comments on commit 34b5a5f

Please sign in to comment.