fix for rare launch race condition

This commit is contained in:
Eric 2023-06-28 18:23:56 -07:00
parent 01bfc232a0
commit f011110967
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
9 changed files with 115 additions and 54 deletions

56
.efrocachemap generated
View File

@ -4068,26 +4068,26 @@
"build/assets/windows/Win32/ucrtbased.dll": "https://files.ballistica.net/cache/ba1/2d/ef/5335207d41b21b9823f6805997f1", "build/assets/windows/Win32/ucrtbased.dll": "https://files.ballistica.net/cache/ba1/2d/ef/5335207d41b21b9823f6805997f1",
"build/assets/windows/Win32/vc_redist.x86.exe": "https://files.ballistica.net/cache/ba1/b0/8a/55e2e77623fe657bea24f223a3ae", "build/assets/windows/Win32/vc_redist.x86.exe": "https://files.ballistica.net/cache/ba1/b0/8a/55e2e77623fe657bea24f223a3ae",
"build/assets/windows/Win32/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/86/5b/2af4d1e26a1a8073c89acb06e599", "build/assets/windows/Win32/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/86/5b/2af4d1e26a1a8073c89acb06e599",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/af/b7/62892190ebe1627f6754cf9b8f81", "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/cc/c6/e6492f9eeb1c6904ad745abe6eee",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/5c/1a/ca899e8d4ed6bc687beb0e38dcd6", "build/prefab/full/linux_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/08/19/389fd56c41b7ecaa5a8ce0030038",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/41/83/dd4dca131a728b0895132fed9460", "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/2e/36/d7de8b609ed2ac99d1e0d5de0ec3",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/76/c3/1390ce3a6f8cc8c8f6fb964acfa6", "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/68/0d/768d03448e5a5d4531dd1a11ebd9",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/7a/08/7bbb34a806cb2496c09dfde676e4", "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/ba/6f/5c4982d5026eb61c97cdd2029b69",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/9a/ec/b1ceae80bb7883223fb452357fb7", "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/5f/b0/3fce5a36c251f4090efa8d5c17f6",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/9f/1c/143dea8c4fe1e3e2d85a8c840e72", "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/41/76/508f80aa2cad4248be0f644ac577",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/81/b0/e1b2ca529888b4404141ed85fead", "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/e2/8c/71a04c5829575d085aef4e36a77f",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/03/9d/1a6c8386f0d400337c4603041b35", "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/50/ea/3425b68d9cbd018b591620ea21c8",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/2e/99/6a8ca74892e6592dbc76a3c7b131", "build/prefab/full/mac_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/ab/c8/e638cf97e0f18c247c87c453d017",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/1c/04/b71e12f876970e293a0e080db9ea", "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/3a/16/39bbdf1fd716309eb9bc00a3914c",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/56/26/881bfb1a0f3c0ffa9be27d879943", "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/60/ff/8ad1713b4fbd20d43b3a791095b3",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/99/f9/f12a44c19406317c097ae87e0778", "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/81/38/d5beff6112f26a82271e6f8430ba",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/5d/ee/d9d65c36efb1caca59f4a8911824", "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/c2/ed/95e885a5bc785a1e595c74ff76dc",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/32/4e/ecd23e2010e07d78f99b82d78b0f", "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/e2/1a/a14431e08d923eb01f6a06132b30",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/08/36/45f7f8d005b350aba84b813a83e8", "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/6d/ab/bb8b72e8764292d17803fbecfcb0",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/ea/8b/dcbc7facc3517832cd087cde8392", "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/3f/7a/37310338d005ba12cab72fdd990d",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/4c/2b/3d925eca850cad90a85110f7363d", "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/de/09/c0e6a848c89c20279a8d562821f7",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/b4/fb/5e7980c7a8af2e54283f3cba8432", "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/59/3a/97b3e97889a8111b1d4fa54e28e9",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/b4/56/d1a2a14e4010e9684d966c723383", "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/9e/e5/ec1673fdc92998ee8952225b46ec",
"build/prefab/lib/linux_arm64_gui/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/be/19/b5458933dfc7371d91ecfcd2e06f", "build/prefab/lib/linux_arm64_gui/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/be/19/b5458933dfc7371d91ecfcd2e06f",
"build/prefab/lib/linux_arm64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/4e/48/123b806cbe6ddb3d9a8368bbb4f8", "build/prefab/lib/linux_arm64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/4e/48/123b806cbe6ddb3d9a8368bbb4f8",
"build/prefab/lib/linux_arm64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/be/19/b5458933dfc7371d91ecfcd2e06f", "build/prefab/lib/linux_arm64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/be/19/b5458933dfc7371d91ecfcd2e06f",
@ -4104,14 +4104,14 @@
"build/prefab/lib/mac_x86_64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/7e/fa/291fd7e935502ced7e99b8c8f7f0", "build/prefab/lib/mac_x86_64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/7e/fa/291fd7e935502ced7e99b8c8f7f0",
"build/prefab/lib/mac_x86_64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/e1/cb/7e8440699e59e8646da25aa5782b", "build/prefab/lib/mac_x86_64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/e1/cb/7e8440699e59e8646da25aa5782b",
"build/prefab/lib/mac_x86_64_server/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/7e/fa/291fd7e935502ced7e99b8c8f7f0", "build/prefab/lib/mac_x86_64_server/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/7e/fa/291fd7e935502ced7e99b8c8f7f0",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/66/17/448c77d6413f25555e40055d154b", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/5d/1c/956723a220dbd69a6fccbdec29df",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/56/b0/7ce3384cfb63d3a224e317c69fa8", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/e5/5c/c7737071206b53292cdc954bfde5",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/b6/73/847160ecfbbbea758f130c03abb8", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/50/78/552f6c71715a4939b0ca67468efc",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/dc/e6/e052a9115ca83686c6634d2c26ff", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/71/5f/bcbdc8e71a29515ed95ec3c33fae",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/2e/56/390279b063b7f8455cf7f1656608", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/de/64/60396bbaba483ff09a421998372a",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/3a/d7/a0329b38db9b594c36ff88a884c9", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/8b/92/725858ebddf7f1d35562ce516e59",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/a5/9b/0802a9d6604fffc0136ac95a5be3", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/15/08/f62cc35c4746f7767059e0e358b5",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/e9/74/5d6a32e3a161a2f5597aa9336b79", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/e4/39/8964fd8d1781fe1d5b09bce43d98",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "https://files.ballistica.net/cache/ba1/f8/85/fed7f2ed98ff2ba271f9dbe3391c", "src/assets/ba_data/python/babase/_mgen/__init__.py": "https://files.ballistica.net/cache/ba1/f8/85/fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "https://files.ballistica.net/cache/ba1/48/4b/e6974f0a4d14be8213dc00d971c3", "src/assets/ba_data/python/babase/_mgen/enums.py": "https://files.ballistica.net/cache/ba1/48/4b/e6974f0a4d14be8213dc00d971c3",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "https://files.ballistica.net/cache/ba1/3e/7a/203e2a5d2b5bb42cfe3fd2fe16c2", "src/ballistica/base/mgen/pyembed/binding_base.inc": "https://files.ballistica.net/cache/ba1/3e/7a/203e2a5d2b5bb42cfe3fd2fe16c2",

View File

@ -1,3 +1,9 @@
### 1.7.22 (build 21154, api 8, 2023-06-28)
- Fixed a very rare race condition when launching threads or sending synchronous
cross-thread messages. This was manifesting as one out of several thousand
server launches hanging.
### 1.7.21 (build 21152, api 8, 2023-06-27) ### 1.7.21 (build 21152, api 8, 2023-06-27)
- Fixed an issue where server builds would not always include collision meshes. - Fixed an issue where server builds would not always include collision meshes.
@ -102,7 +108,7 @@
to the local device. to the local device.
- The `ba.Context` class has been reworked a bit and is now `ba.ContextRef` to - The `ba.Context` class has been reworked a bit and is now `ba.ContextRef` to
more accurately describe what it actually is. The default constructor more accurately describe what it actually is. The default constructor
(`ba.ContextRef()`) will grab a reference to the current context. To get a (`ba.ContextRef()`) will grab a reference to the current context. To get a
context-ref pointing to *no* context, do `ba.ContextRef.empty()`. UI stuff context-ref pointing to *no* context, do `ba.ContextRef.empty()`. UI stuff
will now insist on being run with no context set. To get references to will now insist on being run with no context set. To get references to
Activity/Session contexts, use the context() methods they provide. Activity/Session contexts, use the context() methods they provide.
@ -127,7 +133,7 @@
conversions' may want to keep an eye on this. conversions' may want to keep an eye on this.
- There is no longer a standalone `ba.playsound()` function. Both ui-sounds ( - There is no longer a standalone `ba.playsound()` function. Both ui-sounds (
acquired via `bauiv1.getsound()` and scene-sounds (acquired via acquired via `bauiv1.getsound()` and scene-sounds (acquired via
`bascenev1.getsound()`) now have a play() method on them for this purpose. So `bascenev1.getsound()`) now have a play() method on them for this purpose. So
just search for any instances of 'playsound' in your code and change stuff just search for any instances of 'playsound' in your code and change stuff
like `ba.playsound(ba.getsound('error'))` to `bs.getsound('error').play()`. like `ba.playsound(ba.getsound('error'))` to `bs.getsound('error').play()`.
Playing sounds in timers is now especially nicer looking; instead of Playing sounds in timers is now especially nicer looking; instead of
@ -303,8 +309,10 @@
instances of `bastd.ui` with `bauiv1lib` and all other instances of `bastd` instances of `bastd.ui` with `bauiv1lib` and all other instances of `bastd`
with `bascenev1lib`. That should mostly do it. Random tip: check out the with `bascenev1lib`. That should mostly do it. Random tip: check out the
`tools/pcommand mypy_files` as a handy tool to help get your mods updated. `tools/pcommand mypy_files` as a handy tool to help get your mods updated.
- (build 21057) Fixed an issue with news items erroring on the main menu (thanks for the heads up Rikko) - (build 21057) Fixed an issue with news items erroring on the main menu (thanks
- (build 21059) Fixed an issue where trying to add a new playlist would error (thanks for the heads up SEBASTIAN2059) for the heads up Rikko)
- (build 21059) Fixed an issue where trying to add a new playlist would error (
thanks for the heads up SEBASTIAN2059)
- (build 21059) Fixed meta scanning which was coming up empty. Note that games - (build 21059) Fixed meta scanning which was coming up empty. Note that games
must now tag themselves via `ba_meta export bascenev1.GameActivity` instead of must now tag themselves via `ba_meta export bascenev1.GameActivity` instead of
`ba_meta export game` to be discovered. Warnings will be issued if the old tag `ba_meta export game` to be discovered. Warnings will be issued if the old tag
@ -350,7 +358,8 @@
Android would not show correctly under the player. Android would not show correctly under the player.
- (build 21084) Plugin UI now has a categories dropdown for showing only enabled - (build 21084) Plugin UI now has a categories dropdown for showing only enabled
or disabled plugins (Thanks vishal332008!) or disabled plugins (Thanks vishal332008!)
- (build 21095) Fixed an issue where certain buttons such as map selection buttons - (build 21095) Fixed an issue where certain buttons such as map selection
buttons
would draw incorrectly. would draw incorrectly.
- (build 21106) Fixed an issue where in-game ping would always display green no - (build 21106) Fixed an issue where in-game ping would always display green no
matter how bad the ping was. matter how bad the ping was.
@ -1235,7 +1244,7 @@
cause a crash. cause a crash.
- Fixed a case where an early fatal error could lead to a hung app and no error - Fixed a case where an early fatal error could lead to a hung app and no error
dialog. dialog.
- Added environment variables which can override UI scale for testing. Set - Added environment variables which can override UI scale for testing. Set
`BA_FORCE_UI_SCALE` to small, medium or large. `BA_FORCE_UI_SCALE` to small, medium or large.
- Added a ba.UIScale enum. The value at ba.app.uiscale replaces the old - Added a ba.UIScale enum. The value at ba.app.uiscale replaces the old
`ba.app.interface_type`, `ba.app.small_ui`, and `ba.app.med_ui` values. `ba.app.interface_type`, `ba.app.small_ui`, and `ba.app.med_ui` values.

View File

@ -28,8 +28,8 @@ if TYPE_CHECKING:
# Build number and version of the ballistica binary we expect to be # Build number and version of the ballistica binary we expect to be
# using. # using.
TARGET_BALLISTICA_BUILD = 21152 TARGET_BALLISTICA_BUILD = 21154
TARGET_BALLISTICA_VERSION = '1.7.21' TARGET_BALLISTICA_VERSION = '1.7.22'
_g_env_config: EnvConfig | None = None _g_env_config: EnvConfig | None = None
g_paths_set_failed = False # pylint: disable=invalid-name g_paths_set_failed = False # pylint: disable=invalid-name

View File

@ -49,9 +49,15 @@ void BGDynamics::Step(const Vector3f& cam_pos, int step_millisecs) {
TooSlow(); TooSlow();
} }
// If we're slightly behind, just don't send this step; // If we're slightly behind, just don't send this step; the bg dynamics
// the bg dynamics will slow down a bit but nothing will disappear this way. // will slow down a bit but nothing will disappear this way, which should
if (step_count > 1) return; // be less jarring.
//
// HMMM; wondering if this should be limited in some way; it might lead to
// oddly slow feeling bg sims if things are consistently slow.
if (step_count > 1) {
return;
}
// Pass a newly allocated raw pointer to the bg-dynamics thread; it takes care // Pass a newly allocated raw pointer to the bg-dynamics thread; it takes care
// of disposing it when done. // of disposing it when done.

View File

@ -2281,7 +2281,7 @@ void BGDynamicsServer::Step(StepData* step_data) {
// data. // data.
auto ref(Object::CompleteDeferred(step_data)); auto ref(Object::CompleteDeferred(step_data));
// Keep this in sync with the game thread's. // Keep our quality in sync with the graphics thread's.
graphics_quality_ = g_base->graphics_server->graphics_quality(); graphics_quality_ = g_base->graphics_server->graphics_quality();
cam_pos_ = step_data->cam_pos; cam_pos_ = step_data->cam_pos;
@ -2352,6 +2352,13 @@ void BGDynamicsServer::Step(StepData* step_data) {
step_count_--; step_count_--;
} }
assert(step_count_ >= 0); assert(step_count_ >= 0);
// Math sanity check.
if (step_count_ < 0) {
BA_LOG_ONCE(LogLevel::kWarning, "BGDynamics step_count too low ("
+ std::to_string(step_count_)
+ "); should not happen.");
}
} }
void BGDynamicsServer::PushStep(StepData* data) { void BGDynamicsServer::PushStep(StepData* data) {
@ -2361,6 +2368,13 @@ void BGDynamicsServer::PushStep(StepData* data) {
step_count_++; step_count_++;
} }
// Client thread should stop feeding us if we get clogged up.
if (step_count_ > 5) {
BA_LOG_ONCE(LogLevel::kWarning, "BGDynamics step_count too high ("
+ std::to_string(step_count_)
+ "); should not happen.");
}
event_loop()->PushCall([this, data] { Step(data); }); event_loop()->PushCall([this, data] { Step(data); });
} }

View File

@ -72,10 +72,10 @@ class Logic {
auto display_time_microsecs() { return display_time_microsecs_; } auto display_time_microsecs() { return display_time_microsecs_; }
/// Return current display-time increment in seconds. /// Return current display-time increment in seconds.
auto display_time_increment() -> double { return display_time_increment_; } auto display_time_increment() { return display_time_increment_; }
/// Return current display-time increment in microseconds. /// Return current display-time increment in microseconds.
auto display_time_increment_microsecs() -> double { auto display_time_increment_microsecs() {
return display_time_increment_microsecs_; return display_time_increment_microsecs_;
} }

View File

@ -39,8 +39,8 @@ auto main(int argc, char** argv) -> int {
namespace ballistica { namespace ballistica {
// These are set automatically via script; don't modify them here. // These are set automatically via script; don't modify them here.
const int kEngineBuildNumber = 21152; const int kEngineBuildNumber = 21154;
const char* kEngineVersion = "1.7.21"; const char* kEngineVersion = "1.7.22";
auto MonolithicMain(const core::CoreConfig& core_config) -> int { auto MonolithicMain(const core::CoreConfig& core_config) -> int {
// This code is meant to be run standalone so won't inherit any // This code is meant to be run standalone so won't inherit any

View File

@ -19,6 +19,15 @@ EventLoop::EventLoop(EventLoopID identifier_in, ThreadSource source)
: source_(source), identifier_(identifier_in) { : source_(source), identifier_(identifier_in) {
switch (source_) { switch (source_) {
case ThreadSource::kCreate: { case ThreadSource::kCreate: {
// IMPORTANT: We grab this lock *before* kicking off our thread, and
// we hold it until we're actively listening for the completion
// notification. The new thread also grabs the lock before notifying
// us, which ensures that we've reached the waiting state before the
// notification happens. Otherwise it is possible for them to push out
// a notification before we start waiting for it, which means we hang
// when we do start listening and nothing comes in.
std::unique_lock lock(client_listener_mutex_);
int (*func)(void*); int (*func)(void*);
void* (*funcp)(void*); void* (*funcp)(void*);
switch (identifier_) { switch (identifier_) {
@ -80,7 +89,6 @@ EventLoop::EventLoop(EventLoopID identifier_in, ThreadSource source)
g_core->LifecycleLog("logic thread bootstrap wait begin"); g_core->LifecycleLog("logic thread bootstrap wait begin");
} }
std::unique_lock lock(client_listener_mutex_);
client_listener_cv_.wait(lock, [this] { return bootstrapped_; }); client_listener_cv_.wait(lock, [this] { return bootstrapped_; });
if (identifier_ == EventLoopID::kLogic) { if (identifier_ == EventLoopID::kLogic) {
@ -392,6 +400,14 @@ auto EventLoop::ThreadMain() -> int {
// Mark ourself as bootstrapped and signal listeners so // Mark ourself as bootstrapped and signal listeners so
// anyone waiting for us to spin up can move along. // anyone waiting for us to spin up can move along.
bootstrapped_ = true; bootstrapped_ = true;
{
// Momentarily grab this lock. This ensures that whoever launched us
// is now actively waiting for this notification. If we skipped this
// it would be possible to notify before they start listening which
// leads to a hang.
std::unique_lock lock(client_listener_mutex_);
}
client_listener_cv_.notify_all(); client_listener_cv_.notify_all();
// Now just run our loop until we die. // Now just run our loop until we die.
@ -663,6 +679,13 @@ void EventLoop::RunPendingRunnables() {
} }
} }
if (do_notify_listeners) { if (do_notify_listeners) {
{
// Momentarily grab this lock. This ensures that whoever pushed us is
// now actively waiting for completion notification. If we skipped
// this it would be possible to notify before they start listening
// which leads to a hang.
std::unique_lock lock(client_listener_mutex_);
}
client_listener_cv_.notify_all(); client_listener_cv_.notify_all();
} }
} }
@ -714,6 +737,16 @@ void EventLoop::PushRunnable(Runnable* runnable) {
void EventLoop::PushRunnableSynchronous(Runnable* runnable) { void EventLoop::PushRunnableSynchronous(Runnable* runnable) {
bool complete{}; bool complete{};
bool* complete_ptr{&complete}; bool* complete_ptr{&complete};
// IMPORTANT: We grab this lock *before* pushing our runnable, and we hold
// it until we're actively listening for the completion notification. The
// receiver also grabs the lock before notifying us, which ensures that
// we've reached the waiting state before the notification happens.
// Otherwise it is possible for them to push out a notification before we
// start waiting for it, which means we hang when we do start listening
// and nothing comes in.
std::unique_lock lock(client_listener_mutex_);
if (std::this_thread::get_id() == thread_id()) { if (std::this_thread::get_id() == thread_id()) {
FatalError( FatalError(
"PushRunnableSynchronous called from target thread;" "PushRunnableSynchronous called from target thread;"
@ -727,7 +760,6 @@ void EventLoop::PushRunnableSynchronous(Runnable* runnable) {
} }
// Now listen until our completion flag gets set. // Now listen until our completion flag gets set.
std::unique_lock lock(client_listener_mutex_);
client_listener_cv_.wait(lock, [complete_ptr] { client_listener_cv_.wait(lock, [complete_ptr] {
// Go back to sleep on spurious wakeups // Go back to sleep on spurious wakeups
// (if we're not actually complete yet). // (if we're not actually complete yet).

View File

@ -90,14 +90,14 @@
} \ } \
((void)0) // (see 'Trailing-semicolon note' at top) ((void)0) // (see 'Trailing-semicolon note' at top)
#define BA_LOG_ONCE(lvl, msg) \ #define BA_LOG_ONCE(lvl, msg) \
{ \ { \
static bool did_log_here = false; \ static bool did_log_here{}; \
if (!did_log_here) { \ if (!did_log_here) { \
::ballistica::Log(lvl, msg); \ ::ballistica::Log(lvl, msg); \
did_log_here = true; \ did_log_here = true; \
} \ } \
} \ } \
((void)0) // (see 'Trailing-semicolon note' at top) ((void)0) // (see 'Trailing-semicolon note' at top)
#define BA_LOG_PYTHON_TRACE(msg) ::ballistica::MacroLogPythonTrace(g_core, msg) #define BA_LOG_PYTHON_TRACE(msg) ::ballistica::MacroLogPythonTrace(g_core, msg)