Skip to content

Commit 8ba0653

Browse files
authored
Merge pull request #803 from ngmr/refactor/store-config-in-WrappedReplyInputStream
refactor(yoko-core): use LazyReference for thread local frame management in WrappedReplyInputStream
2 parents 72d3883 + 405e73e commit 8ba0653

1 file changed

Lines changed: 48 additions & 3 deletions

File tree

yoko-core/src/main/java/org/apache/yoko/orb/OB/WrappedReplyInputStream.java

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@
1717
*/
1818
package org.apache.yoko.orb.OB;
1919

20+
import org.apache.yoko.io.SimplyCloseable;
2021
import org.apache.yoko.orb.CORBA.YokoInputStream;
22+
import org.apache.yoko.util.cmsf.Cmsf;
23+
import org.apache.yoko.util.concurrent.LazyReference;
24+
import org.apache.yoko.util.rofl.Rofl;
25+
import org.apache.yoko.util.yasf.Yasf;
2126
import org.omg.CORBA.Any;
2227
import org.omg.CORBA.Context;
2328
import org.omg.CORBA.INTERNAL;
@@ -30,9 +35,13 @@
3035

3136
import java.io.Serializable;
3237
import java.math.BigDecimal;
38+
import java.util.Set;
3339
import java.util.function.Supplier;
3440

3541
import static org.apache.yoko.util.Exceptions.as;
42+
import static org.apache.yoko.util.ThreadLocalStack.CMSF_THREAD_LOCAL;
43+
import static org.apache.yoko.util.ThreadLocalStack.ROFL_THREAD_LOCAL;
44+
import static org.apache.yoko.util.ThreadLocalStack.YASF_THREAD_LOCAL;
3645

3746
/**
3847
* Wrapper for InputStream that intercepts the first read operation to trigger
@@ -46,18 +55,47 @@ final class WrappedReplyInputStream extends InputStream {
4655
private final YokoInputStream yokoStream;
4756
private final Downcall downcall;
4857
private boolean readYet;
58+
private final LazyReference<Supplier<SimplyCloseable>> configFrameRef;
4959

5060
WrappedReplyInputStream(YokoInputStream yokoStream, Downcall downcall) {
5161
this.yokoStream = yokoStream;
5262
this.downcall = downcall;
63+
64+
// Initialize LazyReference with a function that captures thread local values and returns a Supplier
65+
// The Supplier, when invoked, pushes captured values and returns a composite closer
66+
this.configFrameRef = new LazyReference<>(() -> {
67+
// Capture current thread local values at initialization time
68+
final Set<Yasf> yasf = YASF_THREAD_LOCAL.get();
69+
final Cmsf cmsf = CMSF_THREAD_LOCAL.get();
70+
final Rofl rofl = ROFL_THREAD_LOCAL.get();
71+
72+
// Return a Supplier that pushes the captured values and returns a composite closer
73+
return () -> {
74+
// Push the captured values onto their respective thread local stacks
75+
@SuppressWarnings("resource")
76+
SimplyCloseable ignored0 = YASF_THREAD_LOCAL.push(yasf);
77+
@SuppressWarnings("resource")
78+
SimplyCloseable ignored1 = CMSF_THREAD_LOCAL.push(cmsf);
79+
@SuppressWarnings("resource")
80+
SimplyCloseable ignored2 = ROFL_THREAD_LOCAL.push(rofl);
81+
82+
// Return a composite SimplyCloseable that pops all three in reverse order
83+
return () -> {
84+
ROFL_THREAD_LOCAL.pop();
85+
CMSF_THREAD_LOCAL.pop();
86+
YASF_THREAD_LOCAL.pop();
87+
};
88+
};
89+
});
5390
}
5491

5592
/**
5693
* Wraps a read operation with first-read interception logic.
5794
* Handles both value-returning and void operations uniformly.
95+
* Establishes thread local frame before unmarshalling.
5896
*/
5997
private <T> T wrapRead(Supplier<T> readOp) {
60-
try {
98+
try (SimplyCloseable ignored = configFrameRef.get().get()) {
6199
T result = readOp.get();
62100
triggerInterceptorsOnFirstRead();
63101
return result;
@@ -68,9 +106,10 @@ private <T> T wrapRead(Supplier<T> readOp) {
68106

69107
/**
70108
* Wraps a void read operation (array reads) with first-read interception logic.
109+
* Establishes thread local frame before unmarshalling.
71110
*/
72111
private void wrapVoidRead(Runnable readOp) {
73-
try {
112+
try (SimplyCloseable ignored = configFrameRef.get().get()) {
74113
readOp.run();
75114
triggerInterceptorsOnFirstRead();
76115
} catch (SystemException ex) {
@@ -81,6 +120,11 @@ private void wrapVoidRead(Runnable readOp) {
81120
/**
82121
* Called before the first read operation returns to trigger interceptors.
83122
* Subsequent reads bypass this check.
123+
* <p>
124+
* <em>Note: this approach may be insufficient in the edge case of an IDL-defined
125+
* interface with out or inout parameters in addition to the return value,
126+
* but only if those subsequent values are unmarshalled differently according to context
127+
* (e.g. YASF, CMSF, or ROFL).</em>
84128
*/
85129
private void triggerInterceptorsOnFirstRead() throws SystemException {
86130
if (readYet) return;
@@ -98,11 +142,12 @@ private void triggerInterceptorsOnFirstRead() throws SystemException {
98142
/**
99143
* Handles SystemException during first read by reporting to interceptors
100144
* via receive_exception before propagating the exception.
145+
* Establishes thread local frame before unmarshalling exception.
101146
*/
102147
private <T> T handleFirstReadException(SystemException ex) throws SystemException {
103148
if (readYet) throw ex;
104149
readYet = true;
105-
try {
150+
try (SimplyCloseable ignored = configFrameRef.get().get()) {
106151
downcall.unmarshalEx(ex);
107152
downcall.postUnmarshal();
108153
throw ex;

0 commit comments

Comments
 (0)