Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
Alchemy Viewer
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Deploy
Releases
Package registry
Operate
Terraform modules
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Silent mode is enabled
All outbound communications are blocked.
Learn more
.
Show more breadcrumbs
Alchemy Viewer
Alchemy Viewer
Commits
b7d60f65
Commit
b7d60f65
authored
4 years ago
by
Nat Goodspeed
Browse files
Options
Downloads
Patches
Plain Diff
DRTVWR-476: Fix LLCoprocedurePool::enqueueCoprocedure() shutdown crash.
parent
a07553c2
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
indra/llmessage/llcoproceduremanager.cpp
+34
-11
34 additions, 11 deletions
indra/llmessage/llcoproceduremanager.cpp
with
34 additions
and
11 deletions
indra/llmessage/llcoproceduremanager.cpp
+
34
−
11
View file @
b7d60f65
...
@@ -325,16 +325,22 @@ LLUUID LLCoprocedurePool::enqueueCoprocedure(const std::string &name, LLCoproced
...
@@ -325,16 +325,22 @@ LLUUID LLCoprocedurePool::enqueueCoprocedure(const std::string &name, LLCoproced
LL_INFOS
(
"CoProcMgr"
)
<<
"Coprocedure("
<<
name
<<
") enqueuing with id="
<<
id
.
asString
()
<<
" in pool
\"
"
<<
mPoolName
<<
"
\"
at "
<<
mPending
<<
LL_ENDL
;
LL_INFOS
(
"CoProcMgr"
)
<<
"Coprocedure("
<<
name
<<
") enqueuing with id="
<<
id
.
asString
()
<<
" in pool
\"
"
<<
mPoolName
<<
"
\"
at "
<<
mPending
<<
LL_ENDL
;
auto
pushed
=
mPendingCoprocs
->
try_push
(
boost
::
make_shared
<
QueuedCoproc
>
(
name
,
id
,
proc
));
auto
pushed
=
mPendingCoprocs
->
try_push
(
boost
::
make_shared
<
QueuedCoproc
>
(
name
,
id
,
proc
));
// We don't really have a lot of good options if try_push() failed,
if
(
pushed
==
boost
::
fibers
::
channel_op_status
::
success
)
// perhaps because the consuming coroutine is gummed up or something. This
{
// method is probably called from code called by mainloop. If we toss an
++
mPending
;
// llcoro::suspend() call here, we'll circle back for another mainloop
return
id
;
// iteration, possibly resulting in being re-entered here. Let's avoid that.
}
LL_ERRS_IF
(
pushed
!=
boost
::
fibers
::
channel_op_status
::
success
,
"CoProcMgr"
)
<<
"Enqueue failed because queue is "
<<
int
(
pushed
)
<<
LL_ENDL
;
// Here we didn't succeed in pushing. Shutdown could be the reason.
++
mPending
;
if
(
pushed
==
boost
::
fibers
::
channel_op_status
::
closed
)
{
return
id
;
LL_WARNS
(
"CoProcMgr"
)
<<
"Discarding coprocedure '"
<<
name
<<
"' because shutdown"
<<
LL_ENDL
;
return
{};
}
// The queue should never fill up.
LL_ERRS
(
"CoProcMgr"
)
<<
"Enqueue failed ("
<<
unsigned
(
pushed
)
<<
")"
<<
LL_ENDL
;
return
{};
// never executed, pacify the compiler
}
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
...
@@ -344,6 +350,23 @@ void LLCoprocedurePool::coprocedureInvokerCoro(
...
@@ -344,6 +350,23 @@ void LLCoprocedurePool::coprocedureInvokerCoro(
{
{
for
(;;)
for
(;;)
{
{
// It is VERY IMPORTANT that we instantiate a new ptr_t just before
// the pop_wait_for() call below. When this ptr_t was declared at
// function scope (outside the for loop), NickyD correctly diagnosed a
// mysterious hang condition due to:
// - the second time through the loop, the ptr_t held the last pointer
// to the previous QueuedCoproc, which indirectly held the last
// LLPointer to an LLInventoryCallback instance
// - while holding the lock on pendingCoprocs, pop_wait_for() assigned
// the popped value to the ptr_t variable
// - assignment destroyed the previous value of that variable, which
// indirectly destroyed the LLInventoryCallback
// - whose destructor called ~LLRequestServerAppearanceUpdateOnDestroy()
// - which called LLAppearanceMgr::requestServerAppearanceUpdate()
// - which called enqueueCoprocedure()
// - which tried to acquire the lock on pendingCoprocs... alas.
// Using a fresh, clean ptr_t ensures that no previous value is
// destroyed during pop_wait_for().
QueuedCoproc
::
ptr_t
coproc
;
QueuedCoproc
::
ptr_t
coproc
;
boost
::
fibers
::
channel_op_status
status
;
boost
::
fibers
::
channel_op_status
status
;
{
{
...
@@ -357,7 +380,7 @@ void LLCoprocedurePool::coprocedureInvokerCoro(
...
@@ -357,7 +380,7 @@ void LLCoprocedurePool::coprocedureInvokerCoro(
if
(
status
==
boost
::
fibers
::
channel_op_status
::
timeout
)
if
(
status
==
boost
::
fibers
::
channel_op_status
::
timeout
)
{
{
LL_
INFO
S_ONCE
()
<<
"pool '"
<<
mPoolName
<<
"'
stalled
."
<<
LL_ENDL
;
LL_
DEBUG
S_ONCE
(
"CoProcMgr"
)
<<
"pool '"
<<
mPoolName
<<
"'
waiting
."
<<
LL_ENDL
;
continue
;
continue
;
}
}
// we actually popped an item
// we actually popped an item
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment