Skip to content
Snippets Groups Projects
Forked from Alchemy Viewer / Alchemy Viewer
17280 commits behind the upstream repository.
  • Nicky's avatar
    a2728159
    Replace boost::fibers::unbuffered_channel with boost::fibers::buffered_channel. · a2728159
    Nicky authored
    Using boost::fibers::unbuffered_channel can block the mainthread when calling mPendingCoprocs.push (LLCoprocedurePool::enqueueCoprocedure)
    From the documentation:
    - If a fiber attempts to send a value through an unbuffered channel and no fiber is waiting to receive the value, the channel will block the sending fiber.
    
    This can happen if LLCoprocedurePool::coprocedureInvokerCoro is running a coroutine and this coroutine calls yield, resuming the viewers main loop. If inside
    the main loop someone calls LLCoprocedurePool::enqueueCoprocedure now push will block, as there's no one waiting for a result right now.
    The wait would be in LLCoprocedurePool::coprocedureInvokerCoro at the start of the while loop, but we have not reached that yet again as LLCoprocedurePool::coprocedureInvokerCoro
    did yield before reaching pop_wait_for.
    The result is a deadlock.
    
    boost::fibers::buffered_channel will not block as long as there's space in the channel. A size of 4096 (DEFAULT_QUEUE_SIZE) should be plenty enough for this.
    a2728159
    History
    Replace boost::fibers::unbuffered_channel with boost::fibers::buffered_channel.
    Nicky authored
    Using boost::fibers::unbuffered_channel can block the mainthread when calling mPendingCoprocs.push (LLCoprocedurePool::enqueueCoprocedure)
    From the documentation:
    - If a fiber attempts to send a value through an unbuffered channel and no fiber is waiting to receive the value, the channel will block the sending fiber.
    
    This can happen if LLCoprocedurePool::coprocedureInvokerCoro is running a coroutine and this coroutine calls yield, resuming the viewers main loop. If inside
    the main loop someone calls LLCoprocedurePool::enqueueCoprocedure now push will block, as there's no one waiting for a result right now.
    The wait would be in LLCoprocedurePool::coprocedureInvokerCoro at the start of the while loop, but we have not reached that yet again as LLCoprocedurePool::coprocedureInvokerCoro
    did yield before reaching pop_wait_for.
    The result is a deadlock.
    
    boost::fibers::buffered_channel will not block as long as there's space in the channel. A size of 4096 (DEFAULT_QUEUE_SIZE) should be plenty enough for this.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
llcoproceduremanager.cpp 12.54 KiB