[ https://issues.apache.org/jira/browse/CXF-7575?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16345120#comment-16345120 ]
John Bellassai commented on CXF-7575: ------------------------------------- Sergey, Great, thanks for the fix! I just looked at the commit(s) and I'm pretty sure that you don't want to have removed _volatile_ from all of those member variables without adding _synchronized_ to all of the methods which read or write them. For example, the _doCancel()_ method reads and changes the value of the _cancel_ member variable, but if it's not _synchronized_ or _volatile_, there's no guarantee it will see the most recent value and there's no guarantee that other threads will see the new value. Basically, you're asking for trouble. If you're going to make them non-_volatile_ then you'll probably want to look at revision 005ec0a2ec764f799eb544daa523671109c72a35 and make sure you add _synchronized_ back to all the methods it was removed from in that commit. Otherwise, I don't think there's a big problem in leaving them all _volatile_ even if some of them are also mutex-ed in a _synchronized_ method. > @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 > Assignee: Sergey Beryozkin > Priority: Major > Fix For: 3.1.15, 3.2.2 > > 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)