Skip to content

Commit b8dafa6

Browse files
author
Alan Bateman
committedJan 17, 2024
8323612: IOVecWrapper should be changed to be TerminatingThreadLocal
Reviewed-by: bpb
1 parent f2a4ed6 commit b8dafa6

File tree

2 files changed

+36
-24
lines changed

2 files changed

+36
-24
lines changed
 

‎src/java.base/share/classes/sun/nio/ch/IOUtil.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -259,6 +259,7 @@ static long write(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
259259
vec.clearRefs(j);
260260
}
261261
}
262+
vec.release();
262263
}
263264
}
264265

@@ -470,6 +471,7 @@ static long read(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
470471
vec.clearRefs(j);
471472
}
472473
}
474+
vec.release();
473475
}
474476
}
475477

‎src/java.base/share/classes/sun/nio/ch/IOVecWrapper.java

+33-23
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -26,9 +26,7 @@
2626
package sun.nio.ch;
2727

2828
import java.nio.ByteBuffer;
29-
30-
import jdk.internal.misc.CarrierThreadLocal;
31-
import jdk.internal.ref.CleanerFactory;
29+
import jdk.internal.misc.TerminatingThreadLocal;
3230

3331
/**
3432
* Manipulates a native array of iovec structs on Solaris:
@@ -71,18 +69,20 @@ class IOVecWrapper {
7169
// Address size in bytes
7270
static final int addressSize;
7371

74-
private static class Deallocator implements Runnable {
75-
private final AllocatedNativeObject obj;
76-
Deallocator(AllocatedNativeObject obj) {
77-
this.obj = obj;
72+
// per carrier-thread IOVecWrapper
73+
private static final TerminatingThreadLocal<IOVecWrapper[]> IOV_CACHE = new TerminatingThreadLocal<>() {
74+
@Override
75+
protected IOVecWrapper[] initialValue() {
76+
return new IOVecWrapper[1]; // one slot cache
7877
}
79-
public void run() {
80-
obj.free();
78+
@Override
79+
protected void threadTerminated(IOVecWrapper[] cache) {
80+
IOVecWrapper wrapper = cache[0];
81+
if (wrapper != null) {
82+
wrapper.vecArray.free();
83+
}
8184
}
82-
}
83-
84-
// per carrier-thread IOVecWrapper
85-
private static final CarrierThreadLocal<IOVecWrapper> cached = new CarrierThreadLocal<>();
85+
};
8686

8787
private IOVecWrapper(int size) {
8888
this.size = size;
@@ -95,18 +95,28 @@ private IOVecWrapper(int size) {
9595
}
9696

9797
static IOVecWrapper get(int size) {
98-
IOVecWrapper wrapper = cached.get();
99-
if (wrapper != null && wrapper.size < size) {
100-
// not big enough; eagerly release memory
101-
wrapper.vecArray.free();
102-
wrapper = null;
98+
IOVecWrapper[] cache = IOV_CACHE.get();
99+
IOVecWrapper wrapper = cache[0];
100+
if (wrapper != null) {
101+
cache[0] = null;
102+
if (wrapper.size < size) {
103+
// not big enough; eagerly release memory
104+
wrapper.vecArray.free();
105+
wrapper = null;
106+
}
103107
}
108+
return (wrapper != null) ? wrapper : new IOVecWrapper(size);
109+
}
110+
111+
void release() {
112+
IOVecWrapper[] cache = IOV_CACHE.get();
113+
IOVecWrapper wrapper = cache[0];
104114
if (wrapper == null) {
105-
wrapper = new IOVecWrapper(size);
106-
CleanerFactory.cleaner().register(wrapper, new Deallocator(wrapper.vecArray));
107-
cached.set(wrapper);
115+
cache[0] = this;
116+
} else {
117+
// slot already used
118+
vecArray.free();
108119
}
109-
return wrapper;
110120
}
111121

112122
void setBuffer(int i, ByteBuffer buf, int pos, int rem) {

0 commit comments

Comments
 (0)