1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package io.netty5.buffer.api;
16
17 import io.netty5.util.internal.PlatformDependent;
18 import io.netty5.util.internal.SystemPropertyUtil;
19 import io.netty5.util.internal.logging.InternalLogger;
20 import io.netty5.util.internal.logging.InternalLoggerFactory;
21
22 import java.util.Locale;
23 import java.util.function.Supplier;
24
25 import static io.netty5.util.internal.PlatformDependent.directBufferPreferred;
26 import static java.lang.Runtime.getRuntime;
27
28
29
30
31
32
33
34
35
36
37 public final class DefaultBufferAllocators {
38 private static final InternalLogger logger = InternalLoggerFactory.getInstance(DefaultBufferAllocators.class);
39 private static final BufferAllocator DEFAULT_PREFERRED_ALLOCATOR;
40 private static final BufferAllocator DEFAULT_ON_HEAP_ALLOCATOR;
41 private static final BufferAllocator DEFAULT_OFF_HEAP_ALLOCATOR;
42
43 static {
44 String allocType = SystemPropertyUtil.get(
45 "io.netty5.allocator.type", PlatformDependent.isAndroid() ? "unpooled" : "pooled");
46 allocType = allocType.toLowerCase(Locale.US).trim();
47 boolean directBufferPreferred = directBufferPreferred();
48
49 final BufferAllocator onHeap;
50 final BufferAllocator offHeap;
51 if ("unpooled".equals(allocType)) {
52 onHeap = BufferAllocator.onHeapUnpooled();
53 offHeap = BufferAllocator.offHeapUnpooled();
54 logger.debug("-Dio.netty5.allocator.type: {}", allocType);
55 } else if ("pooled".equals(allocType)) {
56 onHeap = BufferAllocator.onHeapPooled();
57 offHeap = BufferAllocator.offHeapPooled();
58 logger.debug("-Dio.netty5.allocator.type: {}", allocType);
59 } else {
60 onHeap = BufferAllocator.onHeapPooled();
61 offHeap = BufferAllocator.offHeapPooled();
62 logger.debug("-Dio.netty5.allocator.type: pooled (unknown: {})", allocType);
63 }
64 getRuntime().addShutdownHook(new Thread(() -> {
65
66 try (onHeap; offHeap) {
67
68 }
69 }));
70 UncloseableBufferAllocator onHeapUnclosable = new UncloseableBufferAllocator(onHeap);
71 UncloseableBufferAllocator offHeapUnclosable = new UncloseableBufferAllocator(offHeap);
72 DEFAULT_PREFERRED_ALLOCATOR = directBufferPreferred? offHeapUnclosable : onHeapUnclosable;
73 DEFAULT_ON_HEAP_ALLOCATOR = onHeapUnclosable;
74 DEFAULT_OFF_HEAP_ALLOCATOR = offHeapUnclosable;
75 }
76
77 private DefaultBufferAllocators() {
78 }
79
80
81
82
83
84
85
86 public static BufferAllocator preferredAllocator() {
87 return DEFAULT_PREFERRED_ALLOCATOR;
88 }
89
90
91
92
93
94
95
96 public static BufferAllocator onHeapAllocator() {
97 return DEFAULT_ON_HEAP_ALLOCATOR;
98 }
99
100
101
102
103
104
105
106 public static BufferAllocator offHeapAllocator() {
107 return DEFAULT_OFF_HEAP_ALLOCATOR;
108 }
109
110 private static final class UncloseableBufferAllocator implements BufferAllocator {
111 private final BufferAllocator delegate;
112
113 UncloseableBufferAllocator(BufferAllocator delegate) {
114 this.delegate = delegate;
115 }
116
117 @Override
118 public boolean isPooling() {
119 return delegate.isPooling();
120 }
121
122 @Override
123 public AllocationType getAllocationType() {
124 return delegate.getAllocationType();
125 }
126
127 @Override
128 public Buffer allocate(int size) {
129 return delegate.allocate(size);
130 }
131
132 @Override
133 public Supplier<Buffer> constBufferSupplier(byte[] bytes) {
134 return delegate.constBufferSupplier(bytes);
135 }
136
137
138
139
140 @Override
141 public void close() {
142 throw new UnsupportedOperationException("Global default buffer allocator can not be closed explicitly.");
143 }
144 }
145 }