Skip to content

Common: hold thread pool tasks in MoveOnlyFunction - #87

Draft
dayfine wants to merge 8 commits into
mainfrom
common/move-only-function-migrate
Draft

dayfine wants to merge 8 commits into
mainfrom
common/move-only-function-migrate

Conversation

@dayfine

@dayfine dayfine commented Oct 31, 2026 •

Copy link
Copy Markdown
Owner

Based on main, which now has MoveOnlyFunction from PokemonAutomation#1810; the diff shows only this change.

Thread pool tasks are owned by the pool until they run, so ThreadPool now takes them as MoveOnlyFunction<void()> instead of std::function<void()>.

  • dispatch(), dispatch_now_blocking(), try_dispatch_now() and AsyncTask_Cpp's stored task switch to MoveOnlyFunction. A task can now capture move-only state, and can't be forked by an accidental copy.
  • The ~75 callers that pass a lambda are unchanged. The two try_dispatch_now() callers that build the task first (SnapshotManager, SwSh find_sparkles) now build a MoveOnlyFunction.
  • run_in_parallel() keeps const std::function&: it calls the function from many threads through a const reference, which MoveOnlyFunction<void(size_t)> doesn't allow.
  • This is the first per-module batch of the migration Common: add MoveOnlyFunction, a move-only callable wrapper #72 describes. Other std::function uses are left as they are.

Testing

  • Fork CI: Mac (fallback MoveOnlyFunction), Windows clang and Ubuntu (std::move_only_function).
  • All three run the command-line unit tests, which dispatch through the thread pools.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E

dayfine and others added 5 commits October 29, 2026 21:56
std::function is copyable: copying it forks a stateful lambda's state,
and it cannot hold move-only captures. MoveOnlyFunction is an alias of
std::move_only_function where the standard library has it, and a
minimal R(Args...) fallback for Apple's libc++, which lacks it.

Tests: move-only capture, moving keeps one state, empty and nullptr
comparison, reassignment; copy is rejected at compile time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
… tests

The standard does not make std::move_only_function's move assignment
noexcept, and MSVC's STL does not.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
ThreadPool::dispatch(), dispatch_now_blocking() and try_dispatch_now()
take a task that the pool owns until it runs, so it never needs to be
copied. Taking MoveOnlyFunction lets a task capture move-only state and
rules out forking a stateful task by accident. Callers that pass a
lambda are unchanged; the two try_dispatch_now() callers that build the
task first now build a MoveOnlyFunction.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Upstream merged MoveOnlyFunction as PokemonAutomation#1810.
Conflicts in MoveOnlyFunction_Tests.cpp, ComputerPrograms_UnitTestRunner.cpp
and SourceFiles.cmake take main's (PokemonAutomation#1810's) versions; this branch's
migration of the thread pool and its callers is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
@dayfine
dayfine changed the base branch from common/move-only-function to main November 2, 2026 23:18
dayfine and others added 2 commits November 3, 2026 07:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

game:shared Shared or game-neutral code refactor No behavior change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant