Skip to content

Fix AudioProcessor Sendable capture#412

Open
naykutguven wants to merge 3 commits intoargmaxinc:swift-6from
naykutguven:audioprocessor-statelock
Open

Fix AudioProcessor Sendable capture#412
naykutguven wants to merge 3 commits intoargmaxinc:swift-6from
naykutguven:audioprocessor-statelock

Conversation

@naykutguven
Copy link
Contributor

This pull request makes significant improvements to the thread safety and concurrency handling of the AudioProcessor class in AudioProcessor.swift. The main change is the introduction of a lock (stateLock) to serialize access to internal state, making the class safe to use in concurrent contexts such as audio callbacks and async streams. Several properties and methods are updated to use this lock, and the class is marked as @unchecked Sendable to indicate intended concurrency use.

The most important changes include:

Thread Safety and Concurrency Improvements

  • Added a private UnfairLock (stateLock) to serialize all mutations and accesses to internal state, ensuring thread safety when AudioProcessor is used across concurrent contexts. The class is now marked as @unchecked Sendable.
  • All public and internal properties (audioEngine, audioSamples, audioEnergy, relativeEnergyWindow, audioBufferCallback, minBufferLength, and internal storage for these) are now accessed and mutated exclusively under the lock, preventing race conditions.

Method Updates for Locking

  • Updated methods such as processBuffer, purgeAudioSamples, startRecordingLive, resumeRecordingLive, pauseRecording, and stopRecording to use the lock when accessing or mutating state, ensuring all state changes are thread-safe.
  • Ensured that callbacks are invoked outside the lock to avoid potential deadlocks or re-entrant locking issues.

Refactoring and Consistency

  • Refactored property storage to use private "Storage" variables, with public computed properties that use the lock for access.
  • Updated code to consistently use the locked storage variables instead of direct property access throughout the class.

Minor API Behavior Changes

  • When the async stream is terminated, now only stops recording (removes taps and stops the engine) instead of also clearing the callback, since the callback is now cleared in stopRecording.

These changes make AudioProcessor robust for use in multi-threaded and asynchronous scenarios, reducing the risk of data races and undefined behavior.

Copilot AI review requested due to automatic review settings February 11, 2026 16:07
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Improves AudioProcessor concurrency safety by serializing state access behind a lock and marking the class @unchecked Sendable for use across audio callbacks and async streams.

Changes:

  • Introduced stateLock and private *Storage backing fields; migrated public properties to locked computed accessors.
  • Updated buffer processing and recording lifecycle methods to lock around shared state and invoke callbacks outside the lock.
  • Adjusted async stream termination behavior to stop recording without separately clearing the callback.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@naykutguven naykutguven force-pushed the audioprocessor-statelock branch from 1d989b6 to af51181 Compare February 24, 2026 09:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants