1
1
/*
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.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
26
26
package sun .nio .ch ;
27
27
28
28
import java .nio .ByteBuffer ;
29
-
30
- import jdk .internal .misc .CarrierThreadLocal ;
31
- import jdk .internal .ref .CleanerFactory ;
29
+ import jdk .internal .misc .TerminatingThreadLocal ;
32
30
33
31
/**
34
32
* Manipulates a native array of iovec structs on Solaris:
@@ -71,18 +69,20 @@ class IOVecWrapper {
71
69
// Address size in bytes
72
70
static final int addressSize ;
73
71
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
78
77
}
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
+ }
81
84
}
82
- }
83
-
84
- // per carrier-thread IOVecWrapper
85
- private static final CarrierThreadLocal <IOVecWrapper > cached = new CarrierThreadLocal <>();
85
+ };
86
86
87
87
private IOVecWrapper (int size ) {
88
88
this .size = size ;
@@ -95,18 +95,28 @@ private IOVecWrapper(int size) {
95
95
}
96
96
97
97
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
+ }
103
107
}
108
+ return (wrapper != null ) ? wrapper : new IOVecWrapper (size );
109
+ }
110
+
111
+ void release () {
112
+ IOVecWrapper [] cache = IOV_CACHE .get ();
113
+ IOVecWrapper wrapper = cache [0 ];
104
114
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 ();
108
119
}
109
- return wrapper ;
110
120
}
111
121
112
122
void setBuffer (int i , ByteBuffer buf , int pos , int rem ) {
0 commit comments