https://issues.apache.org/bugzilla/show_bug.cgi?id=55715
Bug ID: 55715
Summary: RemoteEndpoint.Async#sendText(String, SendHandler) can
cause StackOverflowErrors and contradicts Oracle's
JavaDoc
Product: Tomcat 8
Version: trunk
Hardware: PC
Status: NEW
Severity: normal
Priority: P2
Component: WebSocket
Assignee: [email protected]
Reporter: [email protected]
See thread on users list [1]:
Tomcat's current implementation of RemoteEndpoint.Async#sendText(String,
SendHandler) can cause StackOverflowErrors (and seems to contradict Oracle's
JavaDoc).
In Tomcat, Async#sendText(...) seems to implemented so that when it could send
all of the data immediately, then it directly calls SendHandler#onResult(...);
whereas when it couldn't send the data immediately, the SendHandler will be
called from another thread.
Oracle's javadoc for RemoteEndpoint.Async says:
"The completion handlers for the asynchronous methods are always called with a
different thread from that which initiated the send."
Now, imagine the case that you want to send 10000 very small text messages to a
client (very unlikely, but possibly could happen). With synchronous I/O
(RemoteEndpoint.Basic), you would do this in this way:
RemoteEndpoint.Basic basic = session.getBasicRemote();
for (int i = 0; i < 10000; i++) {
basic.sendText("Hi, Count: " + i);
}
In this case, there is no problem.
Now imagine you want to do this asynchronously (using a Callback to be informed
when sending is completed), then you could do it this way (e.g. put the
following code in onOpen() method of Tomcat's EchoEndpoint example):
final AtomicInteger aint = new AtomicInteger();
final RemoteEndpoint.Async async = session.getAsyncRemote();
SendHandler handler = new SendHandler() {
@Override
public void onResult(SendResult result) {
int nextVal = aint.incrementAndGet();
if (nextVal < 10000) {
async.sendText("Hi, Count: " + nextVal, this);
}
}
};
async.sendText("Hi, Count: " + aint.get(), handler);
The problem here is that because the messages are very short, Tomcat will be
able to send them immediately, calling the SendHandler#onResult() directly from
Async.sendText(), which will eventually cause a StackOverflowError.
I think if SendHandler#onResult() was always called from a different thread
than the one which calls Async.send... (like the Javadoc says), then although
the performance would probably be worse, StackOverflowErrors shouldn't occur.
[1] http://markmail.org/message/gpxzdwtxtrpynvux
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]