[ 
https://issues.apache.org/jira/browse/CXF-7575?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16344444#comment-16344444
 ] 

John Bellassai edited comment on CXF-7575 at 1/30/18 3:25 AM:
--------------------------------------------------------------

Sergey,

Yes, your breakdown is exactly the situation I was trying to describe.  

I followed the trail of CXF-7037 and found 
[this|https://www.mail-archive.com/dev@tomcat.apache.org/msg110682.html] thread 
in the Tomcat mailing list in which the bug mentioned in CXF-7037 is discussed.

>From what I can tell, the issue in Tomcat was resolved at least in version 
>8.5.6 (2016-10-10). Here is the relevant paragraph from the 
>[changelog|https://tomcat.apache.org/tomcat-8.5-doc/changelog.html]: 
{quote}Refactor the code that implements the requirement that a call to 
complete() or dispatch() made from a non-container thread before the container 
initiated thread that called startAsync() completes must be delayed until the 
container initiated thread has completed. Rather than implementing this by 
blocking the non-container thread, extend the internal state machine to track 
this. This removes the possibility that blocking the non-container thread could 
trigger a deadlock. (markt)
{quote}
So, this would lead me to believe that it is safe to synchronize the 
_doResumeFinal_ method now, at least as far as Tomcat is concerned.


was (Author: jbellassai):
Sergey,

Yes, your breakdown is exactly the situation I was trying to describe.  

I followed the trail of CXF-7037 and found 
[this|https://www.mail-archive.com/dev@tomcat.apache.org/msg110682.html] thread 
in the Tomcat mailing list in which the bug mentioned in CXF-7037 is discussed.

>From what I can tell, the issue in Tomcat was resolved at least in version 
>8.5.6 (2016-10-10). Here is the relevant paragraph from the 
>[changelog|[https://tomcat.apache.org/tomcat-8.5-doc/changelog.html]:] 
{quote}Refactor the code that implements the requirement that a call to 
complete() or dispatch() made from a non-container thread before the container 
initiated thread that called startAsync() completes must be delayed until the 
container initiated thread has completed. Rather than implementing this by 
blocking the non-container thread, extend the internal state machine to track 
this. This removes the possibility that blocking the non-container thread could 
trigger a deadlock. (markt)
{quote}
So, this would lead me to believe that it is safe to synchronize the 
_doResumeFinal_ method now, at least as far as Tomcat is concerned.

> @Suspended race condition
> -------------------------
>
>                 Key: CXF-7575
>                 URL: https://issues.apache.org/jira/browse/CXF-7575
>             Project: CXF
>          Issue Type: Bug
>          Components: JAX-RS
>    Affects Versions: 3.1.14
>            Reporter: John Bellassai
>            Priority: Major
>         Attachments: CXF-7575.patch
>
>
> There appears to be a race condition with the use of AsyncResponseImpl where 
> my user thread can invoke resume() before initialSuspend is set to false by 
> suspendContinuationIfNeeded() and therefore the resume() call does not 
> actually resume the Continuation _and returns true_, indicating that the 
> resume was successful even though it wasn't.
> I've spent all day trying to make sense of this problem and my understanding 
> of how all of this works together is still a bit spotty, but it seems to me 
> that AsyncResponseImpl.suspendContinuationIfNeeded() (or something similar) 
> should be called _before_ invoking the JAXRS method. Right now, that method 
> is only called after the JAXRS method is invoked by JAXRSInvoker so the 
> instance of AsyncResponse passed into the JAXRS method appears to not 
> actually get suspended (or perhaps _marked_ internally as suspended) until 
> after the JAXRS method returns.  If my async task happens to get finished 
> very quickly and calls resume() before that happens, it fails silently.
> I seem to be able to circumvent this problem by running the following at the 
> start of my JAXRS method (pseudo code):
> {code}
> @POST
> @Path(....)
> void myJaxrsMethod(@Suspended AsyncResponse asyncResponse, ...) {
>     if(asyncResponse instanceof AsyncResponseImpl) {
>         ((AsyncResponseImpl)asyncResponse).suspendContinuationIfNeeded()
>     }
>     Runnable asyncTask = createAsyncTask(asyncResponse)
>     submitAsyncTask(asyncTask)
> }
> {code}
> which is why I suspect suspendContinuationIfNeeded() should be called before 
> JAXRSInvoker invokes the JAXRS method.
> One of the things that made this really difficult to track down was that 
> AsyncResponseImpl.resume() returns true even if the Continuation was not 
> resumed! If you make it into doResumeFinal(), like was happening in my case, 
> the return is always true even if cont.resume() is not called. So from user 
> code, it looks like everything is ok, but the response never gets sent to the 
> client.
> This seems somewhat related to the problems reported in CXF-7037



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to