https://bz.apache.org/bugzilla/show_bug.cgi?id=58624

--- Comment #7 from Barry Coughlan <b.coughl...@gmail.com> ---
(In reply to Mark Thomas from comment #6)
> Thanks for all the work on this.
> 
> It is worth updating to the latest 8.0.x in case one of the I/O or
> concurrency updates has improved this.
> 
> I'm switching this to NEEDINFO. Ideally we need a test case but that is not
> essential. If you believe you have found a code path that could trigger this
> let us know and we'll take a look. As long as we can confirm the code path
> is theoretically possible, we'll be happy to fix it.

Hi Mark,

I managed to replicate this on 8.0.24 and 8.0.28. I don't think I could
automate a test to replicate this, but it can be shown with a simple example by
setting breakpoints.

============================================================

Sample server endpoint:

------------------------

package tomcatbug58624;

import javax.websocket.EncodeException;
import javax.websocket.Encoder;
import javax.websocket.EndpointConfig;

public class WsEncoder implements Encoder.Text<Object> {

    @Override
    public void destroy() {
    }

    @Override
    public void init(EndpointConfig endpointConfig) {
    }

    @Override
    public String encode(Object object) throws EncodeException {
        return (String) object;
    }

}

------------------------

package tomcatbug58624;

import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.websocket.CloseReason;
import javax.websocket.EncodeException;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint(value = "/bug58624", encoders = WsEncoder.class)
public class WsEndpoint {

    public static class SendWsMessage implements Runnable {
        private Session session;

        public SendWsMessage(Session session) {
            this.session = session;
        }

        @Override
        public void run() {
            try {
                session.getBasicRemote().sendObject("test");
            } catch (IOException | EncodeException e) {
                e.printStackTrace();
            }
        }

    }

    private static final ExecutorService ex = Executors.newFixedThreadPool(1);

    @OnOpen
    public void onOpen(Session session) throws IOException {
        ex.submit(new SendWsMessage(session));
    }

    @OnMessage
    public void onMessage(String message) {
        System.out.println("OnMessage: " + message);
    }

    @OnError
    public void onError(Throwable t) {
        System.err.println("OnError:");
        t.printStackTrace();
    }

    @OnClose
    public void onClose(Session session, CloseReason cr) {
        System.out.println("Closed " + cr);
    }
}

-----------------------------

Set breakpoint on WsEndpoint$SendWsMessage:29 (The .sendObject() line)
Set breakpoint on WsRemoteEndpointImplServer:76 (start of doWrite())

- Open websocket
  - Thread 1 breaks on sendObject()
- Close websocket from client side (I just did Ctrl+C with Tyrus CLI)
   - Thread 2 breaks on doWrite()
- Continue Thread 1 so that the message gets queued to send
- Continue Thread 2

sendObject() waits indefinitely for Future.get(). The reason is that doWrite is
not set to true in endMessage() because closed = true.

This would happen any time a message is queued to be sent while a close is in
progress.

I’m not familiar enough with the codebase to submit a patch, but it looks to me
like if closed==true in endMessage(), it should call sendResult with an
exception for any messages still in the queue.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to