Wwise SDK 2023.1.5

◆ BatchCancel()

virtual void AK::StreamMgr::IAkLowLevelIOHook::BatchCancel ( AkUInt32  in_uNumTransfers,
BatchIoTransferItem in_pTransferItems,
bool **  io_ppbCancelAllTransfersForThisFile 
pure virtual

Notifies that a transfer request is cancelled. It will be flushed by the streaming device when completed. Cancellation is normal and happens regularly; for example, whenever a sound stops before the end or stops looping. It happens even more frequently when buffering (AkDeviceSettings::fTargetAutoStmBufferLength and AkDeviceSettings::uGranularity) is large and when you low-level IO hook accepts many concurrent requests at the same time.

  • BatchCancel() is an optional functionality that can be implemented as a no-op.
  • BatchCancel() simply informs the Low-Level I/O that a specific transfer will be flushed upon reception. The Low-Level I/O may use this information to stop this transfer right away, or not (it is internally tagged by the high-level device as cancelled). Nevertheless, the callback function MUST be called for cancelled transfers to be resolved.
  • When calling the callback function of a cancelled transfer, pass it AK_Success. Passing AK_Fail to AkAsyncIOTransfer::pCallback has the effect of killing the stream once and for all. This is not what you want.
  • If io_bCancelAllTransfersForThisFile is set, you may cancel all transfers for this file at once. Leave io_bCancelAllTransfersForThisFile to true if you don't want to be called again. For example, if you don't do anything special in BatchCancel(), leave it to true. This will reduce the amount of useless calls. If you set it to false, BatchCancel() will be called again for each remaining pending transfer that need to be cancelled.
  • If io_bCancelAllTransfersForThisFile is not set, BatchCancel() is only called for a subset of pending transfers for this file. You must not set it to true, as BatchCancel() needs to be called explicitly for each transfer that should be cancelled.
  • The calling thread holds the stream's lock. You may call the callback function directly from here (if you can guarantee that the I/O buffer will not be accessed in the meantime), but you must not wait here for another thread to call the callback function.
  • Likewise, if you resolve transfers with your own thread and use a lock to protect your transfers queue, be careful not to run into a deadlock. BatchCancel() can be executed by any thread. Thus, if you need to lock your queue in BatchCancel(), you must never hold this lock when calling back transfers, either from within BatchCancel() or from your worker thread's routine. Lock your list, dequeue the transfer if you can, unlock, and call pCallback if and only if the transfer was found and dequeued. On the other hand, if you choose not to do anything in BatchCancel(), the lock only protects your list between Read()/Write() and your worker thread's routine, and since the device I/O thread does not hold the stream's lock while calling Read()/Write(), your worker thread may therefore hold it while calling back transfers.
  • A race condition exists when cancelling all transfers (io_bCancelAllTransfersForThisFile is true) directly from within this hook. If you handle the io_bCancelAllTransfersForThisFile == true case, you need to defer calling the completion callback to later (from your usual I/O completion thread, for example). This will be fixed in a future version of Wwise.
in_uNumTransfersNumber of transfers to process
in_pTransferItemsList of transfer items to process
io_ppbCancelAllTransfersForThisFileFlag for each transfer indicating whether all transfers should be cancelled for this file (see notes in function description).

Was this page helpful?

Need Support?

Questions? Problems? Need more info? Contact us, and we can help!

Visit our Support page

Tell us about your project. We're here to help.

Register your project and we'll help you get started with no strings attached!

Get started with Wwise