Skip to content

Conversation

@mockersf
Copy link
Member

@mockersf mockersf commented Jan 17, 2026

Objective

ERROR bevy_asset::server: Encountered an I/O error while loading asset: Too many open files (os error 24)

Solution

  • on iOS and macOS, add a Semaphore to ensure we're not opening more than 128 files in parallel

Testing

  • cargo run --release --package bistro works without errors in the log

@mockersf mockersf added A-Assets Load files from disk to use for things like images, models, and sounds O-MacOS Specific to the MacOS (Apple) desktop operating system O-iOS Specific to the iOS mobile operating system labels Jan 17, 2026
@alice-i-cecile alice-i-cecile added the S-Needs-Review Needs reviewer attention (from anyone!) to move forward label Jan 17, 2026
@alice-i-cecile alice-i-cecile added the C-Bug An unexpected or incorrect behavior label Jan 17, 2026
@alice-i-cecile alice-i-cecile added this to the 0.18.1 milestone Jan 17, 2026
Copy link
Contributor

@andriyDev andriyDev left a comment

Choose a reason for hiding this comment

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

I'm a little nervous to do this: you could end up with every running loader acquiring a single file, but then needing a second file to complete, and then being deadlocked.

It's unclear whether this is better than just failing to load. I guess so since it's less likely that users have 128 assets that also need a second file load to complete (e.g., an immediate load). Though having 128 gltfs that reference other textures isn't completely impossible.

@andriyDev
Copy link
Contributor

Also this doesn't take into consideration multiple asset sources. This might need to be a global semaphore?

@mockersf
Copy link
Member Author

I'm a little nervous to do this: you could end up with every running loader acquiring a single file, but then needing a second file to complete, and then being deadlocked.

I've added a timeout of 500ms on acquiring the semaphore, and it continues like before if not possible in that timeout, so it will never block

@mockersf
Copy link
Member Author

Also this doesn't take into consideration multiple asset sources. This might need to be a global semaphore?

I would prefer to have an actual case where this happens before adding it. I'm not a fan of global things, and apple OS + multiple asset sources + many simultaneously open files starts becoming a very specific use case

Copy link
Contributor

@andriyDev andriyDev left a comment

Choose a reason for hiding this comment

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

I don't think we should be treating multiple asset sources as some exotic use case. Users often want to store data in different locations.

But whatever, I'm not gonna block on it. Could we at least add a TODO to consider making the semaphore global to work across multiple asset sources?

@mockersf
Copy link
Member Author

now global

@mockersf mockersf changed the title limit number of open files on macOS and iOS limit number of open files Jan 19, 2026

#[cfg(any(target_os = "macos", target_os = "ios"))]
static OPEN_FILE_LIMITER: Semaphore = Semaphore::new(128);
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
Copy link
Contributor

Choose a reason for hiding this comment

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

Windows doesn't have a limit though. I'd prefer to avoid it for windows? Wdyt?

Copy link
Member Author

@mockersf mockersf Jan 19, 2026

Choose a reason for hiding this comment

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

hoo so it's windows that doesn't have a limit!

#[cfg(any(target_os = "macos", target_os = "ios"))]
static OPEN_FILE_LIMITER: Semaphore = Semaphore::new(128);
#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "windows")))]
static OPEN_FILE_LIMITER: Semaphore = Semaphore::new(512);
Copy link
Contributor

Choose a reason for hiding this comment

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

Where did 512 come from?

Copy link
Member Author

Choose a reason for hiding this comment

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

on macOS it works best with the limit (256) / 2 => 128
so I did the same of linux: 1024 / 2 => 512

Added a comment about it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Assets Load files from disk to use for things like images, models, and sounds C-Bug An unexpected or incorrect behavior O-iOS Specific to the iOS mobile operating system O-MacOS Specific to the MacOS (Apple) desktop operating system S-Needs-Review Needs reviewer attention (from anyone!) to move forward

Projects

None yet

Development

Successfully merging this pull request may close these issues.

On iOS, loading many assets in AssetMode::Processed causes some assets to fail to load

3 participants