Skip to content

Commit

Permalink
fix BlockingContentProducer staying blocked on semaphore when an erro…
Browse files Browse the repository at this point in the history
…r occurs

Signed-off-by: Ludovic Orban <[email protected]>
  • Loading branch information
lorban committed Jan 8, 2025
1 parent 054f268 commit 111337f
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,12 @@ void release()
_condition.signal();
}

void fail()
{
_permits = Integer.MAX_VALUE;
_condition.signal();
}

@Override
public String toString()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,9 @@ public boolean onContentProducible()
// Calling _asyncContentProducer.onContentProducible() changes the channel state from WAITING to WOKEN which
// would prevent the async error thread from noticing that a redispatching is needed.
boolean unready = _asyncContentProducer.isUnready();
boolean error = _asyncContentProducer.isError();
if (LOG.isDebugEnabled())
LOG.debug("onContentProducible releasing semaphore {} unready={}", _semaphore, unready);
LOG.debug("onContentProducible releasing semaphore {} unready={} error={}", _semaphore, unready, error);
// Do not release the semaphore if we are not unready, as certain protocols may call this method
// just after having received the request, not only when they have read all the available content.
if (unready)
Expand All @@ -163,6 +164,8 @@ public boolean onContentProducible()
_asyncContentProducer.getServletChannel().getServletRequestState().onReadIdle();
_semaphore.release();
}
if (error)
_semaphore.fail();
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ protected void service(HttpServletRequest req, HttpServletResponse resp) throws
StackTraceElement[] stackTrace = threadRef.get().getStackTrace();
for (StackTraceElement stackTraceElement : stackTrace)
{
System.out.println(stackTraceElement);
System.err.println(stackTraceElement);
}
}
assertTrue(await);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,12 @@ void release()
_condition.signal();
}

void fail()
{
_permits = Integer.MAX_VALUE;
_condition.signal();
}

@Override
public String toString()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,9 @@ public boolean onContentProducible()
// Calling _asyncContentProducer.onContentProducible() changes the channel state from WAITING to WOKEN which
// would prevent the async error thread from noticing that a redispatching is needed.
boolean unready = _asyncContentProducer.isUnready();
boolean error = _asyncContentProducer.isError();
if (LOG.isDebugEnabled())
LOG.debug("onContentProducible releasing semaphore {} unready={}", _semaphore, unready);
LOG.debug("onContentProducible releasing semaphore {} unready={} error={}", _semaphore, unready, error);
// Do not release the semaphore if we are not unready, as certain protocols may call this method
// just after having received the request, not only when they have read all the available content.
if (unready)
Expand All @@ -163,6 +164,8 @@ public boolean onContentProducible()
_asyncContentProducer.getServletChannel().getServletRequestState().onReadIdle();
_semaphore.release();
}
if (error)
_semaphore.fail();
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ protected void service(HttpServletRequest req, HttpServletResponse resp) throws
StackTraceElement[] stackTrace = threadRef.get().getStackTrace();
for (StackTraceElement stackTraceElement : stackTrace)
{
System.out.println(stackTraceElement);
System.err.println(stackTraceElement);
}
}
assertTrue(await);
Expand Down

0 comments on commit 111337f

Please sign in to comment.