Skip to content

Commit f35903f

Browse files
committed
Catch IllegalReferenceCountException
Closes gh-22594
1 parent 21de098 commit f35903f

File tree

4 files changed

+23
-8
lines changed

4 files changed

+23
-8
lines changed

spring-core/src/main/java/org/springframework/core/codec/AbstractSingleValueEncoder.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
2424
import org.springframework.core.ResolvableType;
2525
import org.springframework.core.io.buffer.DataBuffer;
2626
import org.springframework.core.io.buffer.DataBufferFactory;
27+
import org.springframework.core.io.buffer.DataBufferUtils;
2728
import org.springframework.core.io.buffer.PooledDataBuffer;
2829
import org.springframework.lang.Nullable;
2930
import org.springframework.util.MimeType;
@@ -51,7 +52,7 @@ public final Flux<DataBuffer> encode(Publisher<? extends T> inputStream, DataBuf
5152
return Flux.from(inputStream)
5253
.take(1)
5354
.concatMap(value -> encode(value, bufferFactory, elementType, mimeType, hints))
54-
.doOnDiscard(PooledDataBuffer.class, PooledDataBuffer::release);
55+
.doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release);
5556
}
5657

5758
/**

spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -39,6 +39,9 @@
3939
import java.util.concurrent.atomic.AtomicReference;
4040
import java.util.function.Consumer;
4141

42+
import io.netty.util.IllegalReferenceCountException;
43+
import org.apache.commons.logging.Log;
44+
import org.apache.commons.logging.LogFactory;
4245
import org.reactivestreams.Publisher;
4346
import org.reactivestreams.Subscription;
4447
import reactor.core.publisher.BaseSubscriber;
@@ -60,6 +63,8 @@
6063
*/
6164
public abstract class DataBufferUtils {
6265

66+
private final static Log logger = LogFactory.getLog(DataBufferUtils.class);
67+
6368
private static final Consumer<DataBuffer> RELEASE_CONSUMER = DataBufferUtils::release;
6469

6570

@@ -494,7 +499,15 @@ public static boolean release(@Nullable DataBuffer dataBuffer) {
494499
if (dataBuffer instanceof PooledDataBuffer) {
495500
PooledDataBuffer pooledDataBuffer = (PooledDataBuffer) dataBuffer;
496501
if (pooledDataBuffer.isAllocated()) {
497-
return pooledDataBuffer.release();
502+
try {
503+
return pooledDataBuffer.release();
504+
}
505+
catch (IllegalReferenceCountException ex) {
506+
if (logger.isDebugEnabled()) {
507+
logger.debug("RefCount already at 0", ex);
508+
}
509+
return false;
510+
}
498511
}
499512
}
500513
return false;
@@ -523,7 +536,6 @@ public static Consumer<DataBuffer> releaseConsumer() {
523536
* @return a buffer that is composed from the {@code dataBuffers} argument
524537
* @since 5.0.3
525538
*/
526-
@SuppressWarnings("unchecked")
527539
public static Mono<DataBuffer> join(Publisher<? extends DataBuffer> dataBuffers) {
528540
return join(dataBuffers, -1);
529541
}

spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.springframework.core.codec.Encoder;
3030
import org.springframework.core.codec.Hints;
3131
import org.springframework.core.io.buffer.DataBuffer;
32+
import org.springframework.core.io.buffer.DataBufferUtils;
3233
import org.springframework.core.io.buffer.PooledDataBuffer;
3334
import org.springframework.http.HttpLogging;
3435
import org.springframework.http.MediaType;
@@ -126,13 +127,13 @@ public Mono<Void> write(Publisher<? extends T> inputStream, ResolvableType eleme
126127
.flatMap(buffer -> {
127128
message.getHeaders().setContentLength(buffer.readableByteCount());
128129
return message.writeWith(Mono.just(buffer)
129-
.doOnDiscard(PooledDataBuffer.class, PooledDataBuffer::release));
130+
.doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release));
130131
});
131132
}
132133

133134
if (isStreamingMediaType(contentType)) {
134135
return message.writeAndFlushWith(body.map(buffer ->
135-
Mono.just(buffer).doOnDiscard(PooledDataBuffer.class, PooledDataBuffer::release)));
136+
Mono.just(buffer).doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release)));
136137
}
137138

138139
return message.writeWith(body);

spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartHttpMessageWriter.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.springframework.core.io.Resource;
4141
import org.springframework.core.io.buffer.DataBuffer;
4242
import org.springframework.core.io.buffer.DataBufferFactory;
43+
import org.springframework.core.io.buffer.DataBufferUtils;
4344
import org.springframework.core.io.buffer.PooledDataBuffer;
4445
import org.springframework.core.log.LogFormatUtils;
4546
import org.springframework.http.HttpEntity;
@@ -247,7 +248,7 @@ private Mono<Void> writeMultipart(MultiValueMap<String, ?> map,
247248
Flux<DataBuffer> body = Flux.fromIterable(map.entrySet())
248249
.concatMap(entry -> encodePartValues(boundary, entry.getKey(), entry.getValue(), bufferFactory))
249250
.concatWith(generateLastLine(boundary, bufferFactory))
250-
.doOnDiscard(PooledDataBuffer.class, PooledDataBuffer::release);
251+
.doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release);
251252

252253
return outputMessage.writeWith(body);
253254
}

0 commit comments

Comments
 (0)