diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0869cfc..ea88e43 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,31 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## v2.5.5
+
+### Fixed
+- Fixed `vix run` auto-linking for installed registry dependencies.
+- Fixed script builds using compiled modules such as `kv`.
+- Fixed package export cleanup to avoid duplicate CMake targets in `VixTargets`.
+- Fixed installed module consistency for `threadpool` and `kv`.
+
+### Added
+- Added threadpool examples for validating script and module usage.
+- Added experimental `vix.app` support for simple C++ applications without a visible `CMakeLists.txt`.
+- Added generated CMake project support for `vix.app` based builds and runs.
+- Added experimental documentation for the current `vix.app` design.
+
+### Internal
+- Updated the CLI module with the latest `vix run` dependency linking fixes.
+- Added shared app project resolution for CMake and `vix.app` projects.
+- Added internal CMake generation from `vix.app`.
+- Cleaned umbrella CMake install/export behavior.
+
+### Compatibility
+- No breaking changes.
+- Existing CMake projects keep the current build and run behavior.
+- `vix.app` is experimental and only used when no `CMakeLists.txt` is present.
+
## v2.5.3
### Added
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4f00cc4..e491039 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1395,7 +1395,6 @@ if (VIX_ENABLE_INSTALL)
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/vix/third_party/asio"
)
- # ---- Export umbrella and helper interface targets ----
install(TARGETS vix EXPORT VixTargets)
if (TARGET vix_thirdparty_asio)
diff --git a/README.md b/README.md
index a2b6ab0..24496b9 100644
--- a/README.md
+++ b/README.md
@@ -30,7 +30,7 @@
@@ -43,8 +43,6 @@ Vix.cpp is a modern C++ runtime for building and running real-world applications
Learn more about the Vix runtime in the [documentation](https://docs.vixcpp.com).
-Vix is also the runtime foundation used by [Softadastra](https://docs.softadastra.com), a local-first and offline-first system for building reliable applications that continue working when the network is slow, unstable, or unavailable.
-
## Production Proof
Vix is not a concept. It runs real systems.
@@ -58,8 +56,9 @@ A real-time monitoring system built and running in production with Vix.cpp.
- real-time WebSocket streaming
- production deployment
-🔗 https://pulsegrid.softadastra.com \
-🔗 https://github.com/GaspardKirira/PulseGrid
+Website: 🔗 https://pulsegrid.softadastra.com \
+
+Github: 🔗 https://github.com/GaspardKirira/PulseGrid
Used to build production systems like PulseGrid.
@@ -98,27 +97,6 @@ vix run main.cpp
Done.
-## Replay a previous run
-
-Vix can record a run and replay it later.
-
-```bash
-vix run main.cpp
-vix replay
-```
-
-Replay the latest failed or interrupted run:
-```bash
-vix replay failed
-```
-
-Inspect a recorded run before replaying it:
-```bash
-vix replay show last
-```
-
-Vix stores replay data locally under .vix/runs/, including the command, working directory, exit status, and captured logs.
-
## Build a server
```cpp
@@ -193,50 +171,6 @@ int main(){
}
```
-## API Documentation (HTTP + WebSocket)
-
-Vix automatically exposes a full API documentation.
-
-Start your app, then open:
-
-```
-http://localhost:8080/docs
-```
-
-You get:
-
-- HTTP API documentation
-- WebSocket endpoints
-- Interactive testing UI
-- No external dependencies (offline Swagger UI)
-
-The OpenAPI spec is available at:
-
-```
-http://localhost:8080/openapi.json
-```
-
-### Control docs with `vix run`
-
-Documentation can be enabled or disabled at runtime:
-
-```bash
-# Enable docs
-vix run app.cpp --docs
-
-# Disable docs
-vix run app.cpp --no-docs
-```
-
-### Why this matters
-
-Most systems treat documentation as an afterthought. Vix does not.
-
-- Docs are generated from the runtime
-- Always reflect the real system
-- Work offline
-- Include HTTP and WebSocket
-
## What Vix.cpp gives you
- Run a single `.cpp` file instantly
diff --git a/docs/guides/vix-app.md b/docs/guides/vix-app.md
new file mode 100644
index 0000000..2a89b34
--- /dev/null
+++ b/docs/guides/vix-app.md
@@ -0,0 +1,1074 @@
+# vix.app
+
+`vix.app` is a simple application manifest for C++ projects built with Vix.
+
+It lets small and medium C++ apps start without writing a visible `CMakeLists.txt`.
+
+Vix reads `vix.app`, generates an internal CMake project, then uses CMake and Ninja underneath to build and run the app.
+
+## Goal
+
+`vix.app` is designed for projects that need a simple entry point:
+
+```bash
+vix run
+vix build
+```
+
+without requiring the user to write CMake manually.
+
+The generated CMake project stays internal:
+
+```
+.vix/generated/app/CMakeLists.txt
+```
+
+This means the user gets a simple project format, while Vix keeps the power of the C++ build ecosystem underneath.
+
+## What vix.app does
+
+`vix.app` describes:
+
+- the application name
+- the target type
+- the C++ standard
+- source files
+- include directories
+- compile definitions
+- linked libraries or CMake targets
+
+Example:
+
+```toml
+name = "demo"
+type = "executable"
+standard = "c++20"
+
+sources = [
+ "main.cpp",
+ "hello.cpp"
+]
+
+include_dirs = [
+ "include"
+]
+
+defines = [
+ "DEMO_APP=1"
+]
+
+links = [
+ "vix::core"
+]
+```
+
+Then run:
+
+```bash
+vix run
+```
+
+Vix generates CMake internally, builds the app, and runs the executable.
+
+## What vix.app does not replace
+
+`vix.app` does not replace `vix.json`.
+
+They have different roles.
+
+| File | Role |
+|------|------|
+| `vix.app` | Describes the C++ application target. |
+| `vix.json` | Describes project metadata, registry dependencies, tasks, and workflows. |
+| `vix.lock` | Stores resolved dependency versions. |
+| `.vix/` | Stores generated files, installed dependencies, cache data, and internal metadata. |
+
+The rule is simple:
+
+- `vix.app` = app build description
+- `vix.json` = registry, tasks, workflows, project metadata
+
+## Detection order
+
+Vix keeps existing project behavior intact.
+
+The resolution order is:
+
+```
+1. If CMakeLists.txt exists
+ -> use the existing CMake project
+
+2. Else if vix.app exists
+ -> generate an internal CMake project
+
+3. Else if a single .cpp file is passed
+ -> use single-file mode
+
+4. Else
+ -> show a clear error
+```
+
+This means `vix.app` is only used when there is no `CMakeLists.txt`.
+
+Existing CMake projects keep working as before.
+
+## Minimal project
+
+Project structure:
+
+```
+demo/
+├── main.cpp
+└── vix.app
+```
+
+`main.cpp`:
+
+```cpp
+#include
+
+int main()
+{
+ std::cout << "Hello from Vix app\n";
+ return 0;
+}
+```
+
+`vix.app`:
+
+```toml
+name = "demo"
+type = "executable"
+standard = "c++20"
+
+sources = [
+ "main.cpp"
+]
+```
+
+Run:
+
+```bash
+vix run
+```
+
+Expected output:
+
+```
+Hello from Vix app
+```
+
+## Multi-file project
+
+Project structure:
+
+```
+demo/
+├── main.cpp
+├── hello.cpp
+├── include/
+│ └── hello.hpp
+└── vix.app
+```
+
+`include/hello.hpp`:
+
+```cpp
+#ifndef DEMO_HELLO_HPP
+#define DEMO_HELLO_HPP
+
+void say_hello();
+
+#endif
+```
+
+`hello.cpp`:
+
+```cpp
+#include "hello.hpp"
+
+#include
+
+void say_hello()
+{
+ vix::print("Hello from hello.cpp");
+}
+```
+
+`main.cpp`:
+
+```cpp
+#include "hello.hpp"
+
+#include
+
+int main()
+{
+ vix::print("Hello from main.cpp");
+ say_hello();
+ return 0;
+}
+```
+
+`vix.app`:
+
+```toml
+name = "demo"
+type = "executable"
+standard = "c++20"
+
+sources = [
+ "main.cpp",
+ "hello.cpp"
+]
+
+include_dirs = [
+ "include"
+]
+```
+
+Run:
+
+```bash
+vix run
+```
+
+Expected output:
+
+```
+Hello from main.cpp
+Hello from hello.cpp
+```
+
+## Generated CMake
+
+For the previous example, Vix generates an internal file similar to this:
+
+```cmake
+# Auto-generated by Vix from vix.app
+# Do not edit this file directly.
+
+cmake_minimum_required(VERSION 3.24)
+
+project(demo LANGUAGES CXX)
+
+set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
+
+add_executable(demo
+ "/absolute/path/to/main.cpp"
+ "/absolute/path/to/hello.cpp"
+)
+
+target_include_directories(demo PRIVATE
+ "/absolute/path/to/include"
+)
+```
+
+The generated file is stored under:
+
+```
+.vix/generated/app/CMakeLists.txt
+```
+
+Users should not edit this file directly.
+
+Edit `vix.app` instead.
+
+## Commands
+
+### Build the app
+
+```bash
+vix build
+```
+
+For a `vix.app` project, Vix does this internally:
+
+```
+vix.app
+ -> .vix/generated/app/CMakeLists.txt
+ -> cmake -S .vix/generated/app -B build-ninja -G Ninja
+ -> cmake --build build-ninja
+```
+
+### Run the app
+
+```bash
+vix run
+```
+
+For a `vix.app` project, Vix does this internally:
+
+```
+vix.app
+ -> generate CMake
+ -> build
+ -> run build-ninja/
+```
+
+### Single-file mode still works
+
+```bash
+vix run main.cpp
+```
+
+This keeps the existing script mode behavior.
+
+Use this for quick experiments or one-file programs.
+
+Use `vix.app` when the app has multiple source files or needs includes, definitions, links, or registry dependencies.
+
+## Fields
+
+### name
+
+Required.
+
+Defines the CMake project name and default target name.
+
+```toml
+name = "demo"
+```
+
+Valid examples:
+
+```toml
+name = "api"
+name = "hello"
+name = "softadastra_agent"
+```
+
+The name should be simple and filesystem-friendly.
+
+### type
+
+Optional.
+
+Default:
+
+```toml
+type = "executable"
+```
+
+Supported values:
+
+```toml
+type = "executable"
+type = "static"
+type = "static-library"
+type = "shared"
+type = "shared-library"
+type = "library"
+```
+
+Recommended value for apps:
+
+```toml
+type = "executable"
+```
+
+Example:
+
+```toml
+name = "demo"
+type = "executable"
+```
+
+### standard
+
+Optional.
+
+Default:
+
+```toml
+standard = "c++20"
+```
+
+Supported values:
+
+```toml
+standard = "c++11"
+standard = "c++14"
+standard = "c++17"
+standard = "c++20"
+standard = "c++23"
+standard = "c++26"
+```
+
+Recommended default:
+
+```toml
+standard = "c++20"
+```
+
+### sources
+
+Required.
+
+Lists source files for the app.
+
+```toml
+sources = [
+ "main.cpp",
+ "hello.cpp"
+]
+```
+
+Paths are relative to the project directory.
+
+You can also use files inside `src/`:
+
+```toml
+sources = [
+ "src/main.cpp",
+ "src/server.cpp",
+ "src/routes.cpp"
+]
+```
+
+### include_dirs
+
+Optional.
+
+Lists include directories.
+
+```toml
+include_dirs = [
+ "include"
+]
+```
+
+This generates:
+
+```cmake
+target_include_directories( PRIVATE ...)
+```
+
+Example project:
+
+```
+demo/
+├── include/
+│ └── demo/server.hpp
+├── src/
+│ ├── main.cpp
+│ └── server.cpp
+└── vix.app
+```
+
+`vix.app`:
+
+```toml
+name = "demo"
+type = "executable"
+standard = "c++20"
+
+sources = [
+ "src/main.cpp",
+ "src/server.cpp"
+]
+
+include_dirs = [
+ "include"
+]
+```
+
+### defines
+
+Optional.
+
+Lists preprocessor definitions.
+
+```toml
+defines = [
+ "DEMO_APP=1",
+ "VIX_USE_FAST_PATH"
+]
+```
+
+This generates:
+
+```cmake
+target_compile_definitions( PRIVATE ...)
+```
+
+Example:
+
+```toml
+name = "demo"
+type = "executable"
+standard = "c++20"
+
+sources = [
+ "main.cpp"
+]
+
+defines = [
+ "APP_ENV=\"dev\"",
+ "ENABLE_LOGS=1"
+]
+```
+
+### links
+
+Optional.
+
+Lists libraries or CMake targets linked by the app.
+
+```toml
+links = [
+ "vix::core",
+ "vix::json"
+]
+```
+
+This generates:
+
+```cmake
+target_link_libraries( PRIVATE ...)
+```
+
+Use this field for:
+
+- Vix modules
+- registry package targets
+- local CMake targets exposed through generated dependency files
+- system libraries when appropriate
+
+Example:
+
+```toml
+name = "api"
+type = "executable"
+standard = "c++20"
+
+sources = [
+ "src/main.cpp"
+]
+
+links = [
+ "vix::core",
+ "vix::json"
+]
+```
+
+## Registry dependencies
+
+Registry dependencies stay in `vix.json` and `vix.lock`.
+
+`vix.app` only consumes the targets after they are installed.
+
+Typical flow:
+
+```bash
+vix add softadastra/kordex-runtime
+vix install
+vix run
+```
+
+The project keeps dependency metadata in:
+
+- `vix.json`
+- `vix.lock`
+
+The installed dependency files live under:
+
+```
+.vix/
+```
+
+The generated CMake project can include dependency integration files from `.vix/`, then `links` can reference the exposed CMake targets.
+
+Example `vix.app`:
+
+```toml
+name = "demo"
+type = "executable"
+standard = "c++20"
+
+sources = [
+ "src/main.cpp"
+]
+
+links = [
+ "softadastra::kordex-runtime"
+]
+```
+
+The important separation is:
+
+- `vix.json` handles dependency declaration.
+- `vix.lock` handles resolved versions.
+- `vix.app` links the final targets used by the app.
+
+## Recommended project layout
+
+For a simple app:
+
+```
+demo/
+├── src/
+│ ├── main.cpp
+│ └── app.cpp
+├── include/
+│ └── demo/
+│ └── app.hpp
+├── vix.app
+├── vix.json
+└── vix.lock
+```
+
+Recommended `vix.app`:
+
+```toml
+name = "demo"
+type = "executable"
+standard = "c++20"
+
+sources = [
+ "src/main.cpp",
+ "src/app.cpp"
+]
+
+include_dirs = [
+ "include"
+]
+```
+
+## Full REST API example
+
+Project structure:
+
+```
+rest-api/
+├── src/
+│ └── main.cpp
+└── vix.app
+```
+
+`vix.app`:
+
+```toml
+name = "rest_api"
+type = "executable"
+standard = "c++20"
+
+sources = [
+ "src/main.cpp"
+]
+
+links = [
+ "vix::core"
+]
+```
+
+`src/main.cpp`:
+
+```cpp
+#include
+
+using namespace vix;
+
+int main()
+{
+ App app;
+
+ app.get("/", [](Request &, Response &res){
+ res.json({
+ "message", "Hello from Vix",
+ "framework", "Vix.cpp"
+ });
+ });
+
+ app.get("/health", [](Request &, Response &res){
+ res.json({
+ "ok", true,
+ "service", "rest_api"
+ });
+ });
+
+ app.run(8080);
+ return 0;
+}
+```
+
+Run:
+
+```bash
+vix run
+```
+
+Test:
+
+```bash
+curl -i http://127.0.0.1:8080/
+curl -i http://127.0.0.1:8080/health
+```
+
+## vix.app vs CMakeLists.txt
+
+Use `vix.app` when:
+
+- the app is small or medium-sized
+- you want a fast start
+- you want to avoid writing CMake manually
+- your app has a simple executable target
+- your app has a few source files
+- your app links registry dependencies through Vix
+
+Use `CMakeLists.txt` when:
+
+- the project has advanced build logic
+- the project has many targets
+- the project needs custom CMake functions
+- the project needs advanced install rules
+- the project needs custom toolchains or platform-specific build logic
+- the project is a library intended for complex packaging
+
+The rule is:
+
+- `vix.app` for simple app description.
+- `CMakeLists.txt` for advanced build control.
+
+If both files exist, `CMakeLists.txt` wins.
+
+## Generated files
+
+A `vix.app` project may create:
+
+```
+.vix/generated/app/CMakeLists.txt
+build-ninja/
+build-dev/
+build-release/
+```
+
+These are internal or build output paths.
+
+Recommended `.gitignore`:
+
+```
+build/
+build-*/
+.vix/generated/
+.vix/cache/
+.vix/runs/
+```
+
+Depending on how the project handles dependencies, some `.vix/` dependency files may be local build state and should not be committed.
+
+## Common workflows
+
+### Create a simple app manually
+
+```bash
+mkdir demo
+cd demo
+
+cat > main.cpp <<'CPP'
+#include
+
+int main()
+{
+ vix::print("Hello from Vix app");
+ return 0;
+}
+CPP
+
+cat > vix.app <<'EOF'
+name = "demo"
+type = "executable"
+standard = "c++20"
+
+sources = [
+ "main.cpp"
+]
+EOF
+
+vix run
+```
+
+### Add another source file
+
+```bash
+cat > hello.cpp <<'CPP'
+#include
+
+void say_hello()
+{
+ vix::print("Hello from hello.cpp");
+}
+CPP
+```
+
+Update `main.cpp`:
+
+```cpp
+#include
+
+void say_hello();
+
+int main()
+{
+ vix::print("Hello from main.cpp");
+
+ say_hello();
+
+ return 0;
+}
+```
+
+Update `vix.app`:
+
+```toml
+name = "demo"
+type = "executable"
+standard = "c++20"
+
+sources = [
+ "main.cpp",
+ "hello.cpp"
+]
+```
+
+Run:
+
+```bash
+vix run
+```
+
+### Add an include directory
+
+```
+demo/
+├── include/
+│ └── hello.hpp
+├── main.cpp
+├── hello.cpp
+└── vix.app
+```
+
+`vix.app`:
+
+```toml
+name = "demo"
+type = "executable"
+standard = "c++20"
+
+sources = [
+ "main.cpp",
+ "hello.cpp"
+]
+
+include_dirs = [
+ "include"
+]
+```
+
+### Add registry dependencies
+
+```bash
+vix add namespace/package
+vix install
+```
+
+Then link the target exposed by the package:
+
+```toml
+name = "demo"
+type = "executable"
+standard = "c++20"
+
+sources = [
+ "src/main.cpp"
+]
+
+links = [
+ "namespace::package"
+]
+```
+
+Run:
+
+```bash
+vix run
+```
+
+## Error messages
+
+### Missing vix.app
+
+If no `CMakeLists.txt` and no `vix.app` exist, Vix cannot resolve a project.
+
+Fix:
+
+```bash
+vix run main.cpp
+```
+
+or create `vix.app`:
+
+```toml
+name = "demo"
+type = "executable"
+standard = "c++20"
+
+sources = [
+ "main.cpp"
+]
+```
+
+### Missing sources
+
+Invalid:
+
+```toml
+name = "demo"
+type = "executable"
+standard = "c++20"
+```
+
+Fix:
+
+```toml
+name = "demo"
+type = "executable"
+standard = "c++20"
+
+sources = [
+ "main.cpp"
+]
+```
+
+### Wrong source path
+
+Invalid:
+
+```toml
+sources = [
+ "src/missing.cpp"
+]
+```
+
+Fix the path or create the file.
+
+### Unknown link target
+
+Invalid:
+
+```toml
+links = [
+ "missing::target"
+]
+```
+
+Fix:
+
+- install the dependency
+- check `vix.lock`
+- check the target name exposed by the package
+- check `.vix/` dependency integration files
+- update the `links` field
+
+## Best practices
+
+Keep `vix.app` small.
+
+Recommended:
+
+```toml
+name = "api"
+type = "executable"
+standard = "c++20"
+
+sources = [
+ "src/main.cpp",
+ "src/routes.cpp",
+ "src/server.cpp"
+]
+
+include_dirs = [
+ "include"
+]
+
+links = [
+ "vix::core"
+]
+```
+
+- Avoid turning `vix.app` into a full build system.
+- Do not put registry metadata in `vix.app`.
+- Keep dependencies in `vix.json`.
+- Keep resolved versions in `vix.lock`.
+- Use `CMakeLists.txt` when the app becomes advanced enough to need custom build logic.
+
+## Reference
+
+Complete field reference:
+
+| Field | Required | Default | Purpose |
+|-------|----------|---------|---------|
+| `name` | yes | none | Target and project name. |
+| `type` | no | `executable` | Target type. |
+| `standard` | no | `c++20` | C++ language standard. |
+| `sources` | yes | none | Source files. |
+| `include_dirs` | no | empty | Include directories. |
+| `defines` | no | empty | Compile definitions. |
+| `links` | no | empty | Libraries or CMake targets. |
+
+Supported target types:
+
+| Value | Meaning |
+|-------|---------|
+| `executable` | Builds an executable app. |
+| `static` | Builds a static library. |
+| `static-library` | Builds a static library. |
+| `shared` | Builds a shared library. |
+| `shared-library` | Builds a shared library. |
+| `library` | Builds a static library by default. |
+
+Supported standards:
+
+| Value |
+|-------|
+| `c++11` |
+| `c++14` |
+| `c++17` |
+| `c++20` |
+| `c++23` |
+| `c++26` |
+
+## Summary
+
+`vix.app` gives Vix a simple project-level entry point for C++ apps.
+
+The user writes:
+
+```toml
+name = "demo"
+type = "executable"
+standard = "c++20"
+
+sources = [
+ "main.cpp",
+ "hello.cpp"
+]
+```
+
+Then runs:
+
+```bash
+vix run
+```
+
+Vix handles:
+
+- manifest parsing
+- CMake generation
+- configure
+- build
+- run
+
+The result is a lighter first experience for C++ apps, while keeping CMake and Ninja underneath for the real build work.
diff --git a/examples/threadpool/CMakeLists.txt b/examples/threadpool/CMakeLists.txt
new file mode 100644
index 0000000..93112cf
--- /dev/null
+++ b/examples/threadpool/CMakeLists.txt
@@ -0,0 +1,55 @@
+# @file examples/CMakeLists.txt
+# @author Gaspard Kirira
+#
+# Copyright 2025, Gaspard Kirira. All rights reserved.
+# https://github.com/vixcpp/vix
+# Use of this source code is governed by a MIT license
+# that can be found in the License file.
+#
+# ====================================================================
+# Vix.cpp - Threadpool Examples
+# ====================================================================
+
+set(VIX_THREADPOOL_EXAMPLE_SOURCES
+ basic_post.cpp
+ custom_config.cpp
+ metrics.cpp
+ parallel_for.cpp
+ parallel_for_each.cpp
+ parallel_map.cpp
+ parallel_reduce.cpp
+ periodic_task.cpp
+ shutdown.cpp
+ submit_future.cpp
+ task_cancellation.cpp
+ task_group.cpp
+ task_priority.cpp
+ task_timeout.cpp
+)
+
+foreach(example_source IN LISTS VIX_THREADPOOL_EXAMPLE_SOURCES)
+ get_filename_component(example_name "${example_source}" NAME_WE)
+
+ add_executable(${example_name}
+ ${example_source}
+ )
+
+ target_link_libraries(${example_name}
+ PRIVATE
+ vix::threadpool
+ )
+
+ target_compile_features(${example_name}
+ PRIVATE
+ cxx_std_20
+ )
+
+ if (NOT MSVC)
+ target_compile_options(${example_name}
+ PRIVATE
+ -Wall
+ -Wextra
+ -Wpedantic
+ )
+ endif()
+endforeach()
diff --git a/examples/threadpool/basic_post.cpp b/examples/threadpool/basic_post.cpp
new file mode 100644
index 0000000..3cb3fcd
--- /dev/null
+++ b/examples/threadpool/basic_post.cpp
@@ -0,0 +1,43 @@
+/**
+ *
+ * @file basic_post.cpp
+ * @author Gaspard Kirira
+ *
+ * Copyright 2025, Gaspard Kirira.
+ * All rights reserved.
+ * https://github.com/vixcpp/vix
+ *
+ * Use of this source code is governed by a MIT license
+ * that can be found in the License file.
+ *
+ * Vix.cpp
+ *
+ */
+#include
+#include
+
+#include
+
+int main()
+{
+ vix::threadpool::ThreadPool pool(4);
+
+ std::atomic counter{0};
+
+ for (int i = 0; i < 10; ++i)
+ {
+ pool.post(
+ [&counter]()
+ {
+ counter.fetch_add(1, std::memory_order_relaxed);
+ });
+ }
+
+ pool.wait_idle();
+
+ std::cout << "Executed tasks: " << counter.load() << '\n';
+
+ pool.shutdown();
+
+ return 0;
+}
diff --git a/examples/threadpool/custom_config.cpp b/examples/threadpool/custom_config.cpp
new file mode 100644
index 0000000..069cd96
--- /dev/null
+++ b/examples/threadpool/custom_config.cpp
@@ -0,0 +1,64 @@
+/**
+ *
+ * @file custom_config.cpp
+ * @author Gaspard Kirira
+ *
+ * Copyright 2025, Gaspard Kirira.
+ * All rights reserved.
+ * https://github.com/vixcpp/vix
+ *
+ * Use of this source code is governed by a MIT license
+ * that can be found in the License file.
+ *
+ * Vix.cpp
+ *
+ */
+#include
+#include
+#include
+
+#include
+
+int main()
+{
+ vix::threadpool::ThreadPoolConfig config;
+
+ config.thread_count = 2;
+ config.max_thread_count = 2;
+ config.max_queue_size = 16;
+ config.default_priority = vix::threadpool::TaskPriority::normal;
+ config.allow_dynamic_growth = false;
+ config.drain_on_shutdown = true;
+ config.swallow_task_exceptions = true;
+ config.default_timeout = std::chrono::milliseconds{0};
+
+ vix::threadpool::ThreadPool pool(config);
+
+ auto first =
+ pool.submit(
+ []()
+ {
+ return 10;
+ });
+
+ auto second =
+ pool.submit(
+ []()
+ {
+ return 32;
+ });
+
+ const int result = first.get() + second.get();
+
+ std::cout << "Thread count: " << pool.thread_count() << '\n';
+ std::cout << "Result: " << result << '\n';
+
+ const vix::threadpool::ThreadPoolMetrics metrics = pool.metrics();
+
+ std::cout << "Completed tasks: " << metrics.completed_tasks << '\n';
+ std::cout << "Rejected tasks: " << metrics.rejected_tasks << '\n';
+
+ pool.shutdown();
+
+ return 0;
+}
diff --git a/examples/threadpool/metrics.cpp b/examples/threadpool/metrics.cpp
new file mode 100644
index 0000000..2c5c164
--- /dev/null
+++ b/examples/threadpool/metrics.cpp
@@ -0,0 +1,55 @@
+/**
+ *
+ * @file metrics.cpp
+ * @author Gaspard Kirira
+ *
+ * Copyright 2025, Gaspard Kirira.
+ * All rights reserved.
+ * https://github.com/vixcpp/vix
+ *
+ * Use of this source code is governed by a MIT license
+ * that can be found in the License file.
+ *
+ * Vix.cpp
+ *
+ */
+#include
+#include
+#include
+
+#include
+
+int main()
+{
+ vix::threadpool::ThreadPool pool(4);
+
+ for (int i = 0; i < 8; ++i)
+ {
+ pool.post(
+ []()
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds{20});
+ });
+ }
+
+ pool.wait_idle();
+
+ const vix::threadpool::ThreadPoolMetrics metrics = pool.metrics();
+ const vix::threadpool::ThreadPoolStats stats = pool.stats();
+
+ std::cout << "Worker count: " << metrics.worker_count << '\n';
+ std::cout << "Pending tasks: " << metrics.pending_tasks << '\n';
+ std::cout << "Active tasks: " << metrics.active_tasks << '\n';
+ std::cout << "Completed tasks: " << metrics.completed_tasks << '\n';
+ std::cout << "Failed tasks: " << metrics.failed_tasks << '\n';
+ std::cout << "Rejected tasks: " << metrics.rejected_tasks << '\n';
+ std::cout << "Idle: " << (metrics.idle() ? "yes" : "no") << '\n';
+
+ std::cout << "Accepted tasks: " << stats.accepted_tasks << '\n';
+ std::cout << "Finished tasks: " << stats.finished_tasks() << '\n';
+ std::cout << "Error tasks: " << stats.error_tasks() << '\n';
+
+ pool.shutdown();
+
+ return 0;
+}
diff --git a/examples/threadpool/parallel_for.cpp b/examples/threadpool/parallel_for.cpp
new file mode 100644
index 0000000..d3f9d7a
--- /dev/null
+++ b/examples/threadpool/parallel_for.cpp
@@ -0,0 +1,52 @@
+/**
+ *
+ * @file parallel_for.cpp
+ * @author Gaspard Kirira
+ *
+ * Copyright 2025, Gaspard Kirira.
+ * All rights reserved.
+ * https://github.com/vixcpp/vix
+ *
+ * Use of this source code is governed by a MIT license
+ * that can be found in the License file.
+ *
+ * Vix.cpp
+ *
+ */
+#include
+#include
+#include
+#include
+
+#include
+
+int main()
+{
+ vix::threadpool::ThreadPool pool(4);
+
+ std::vector values(20, 0);
+
+ vix::threadpool::parallel_for(
+ pool,
+ std::size_t{0},
+ values.size(),
+ [&values](std::size_t index)
+ {
+ values[index] = static_cast(index * index);
+ });
+
+ pool.wait_idle();
+
+ std::cout << "parallel_for result:";
+
+ for (const int value : values)
+ {
+ std::cout << ' ' << value;
+ }
+
+ std::cout << '\n';
+
+ pool.shutdown();
+
+ return 0;
+}
diff --git a/examples/threadpool/parallel_for_each.cpp b/examples/threadpool/parallel_for_each.cpp
new file mode 100644
index 0000000..6014483
--- /dev/null
+++ b/examples/threadpool/parallel_for_each.cpp
@@ -0,0 +1,48 @@
+/**
+ *
+ * @file parallel_for_each.cpp
+ * @author Gaspard Kirira
+ *
+ * Copyright 2025, Gaspard Kirira.
+ * All rights reserved.
+ * https://github.com/vixcpp/vix
+ *
+ * Use of this source code is governed by a MIT license
+ * that can be found in the License file.
+ *
+ * Vix.cpp
+ *
+ */
+#include
+#include
+#include
+#include
+
+#include
+
+int main()
+{
+ vix::threadpool::ThreadPool pool(4);
+
+ std::vector names{
+ "vix",
+ "threadpool",
+ "parallel",
+ "runtime"};
+
+ std::mutex mutex;
+
+ vix::threadpool::parallel_for_each(
+ pool,
+ names,
+ [&mutex](const std::string &name)
+ {
+ std::lock_guard lock(mutex);
+ std::cout << "Processing: " << name << '\n';
+ });
+
+ pool.wait_idle();
+ pool.shutdown();
+
+ return 0;
+}
diff --git a/examples/threadpool/parallel_map.cpp b/examples/threadpool/parallel_map.cpp
new file mode 100644
index 0000000..cc5215a
--- /dev/null
+++ b/examples/threadpool/parallel_map.cpp
@@ -0,0 +1,49 @@
+/**
+ *
+ * @file parallel_map.cpp
+ * @author Gaspard Kirira
+ *
+ * Copyright 2025, Gaspard Kirira.
+ * All rights reserved.
+ * https://github.com/vixcpp/vix
+ *
+ * Use of this source code is governed by a MIT license
+ * that can be found in the License file.
+ *
+ * Vix.cpp
+ *
+ */
+#include
+#include
+#include
+
+#include
+
+int main()
+{
+ vix::threadpool::ThreadPool pool(4);
+
+ std::vector numbers{1, 2, 3, 4, 5, 6, 7, 8};
+
+ std::vector squares =
+ vix::threadpool::parallel_map(
+ pool,
+ numbers,
+ [](int value)
+ {
+ return value * value;
+ });
+
+ std::cout << "Squares:";
+
+ for (const int value : squares)
+ {
+ std::cout << ' ' << value;
+ }
+
+ std::cout << '\n';
+
+ pool.shutdown();
+
+ return 0;
+}
diff --git a/examples/threadpool/parallel_reduce.cpp b/examples/threadpool/parallel_reduce.cpp
new file mode 100644
index 0000000..4425073
--- /dev/null
+++ b/examples/threadpool/parallel_reduce.cpp
@@ -0,0 +1,45 @@
+/**
+ *
+ * @file parallel_reduce.cpp
+ * @author Gaspard Kirira
+ *
+ * Copyright 2025, Gaspard Kirira.
+ * All rights reserved.
+ * https://github.com/vixcpp/vix
+ *
+ * Use of this source code is governed by a MIT license
+ * that can be found in the License file.
+ *
+ * Vix.cpp
+ *
+ */
+#include
+#include
+#include
+
+#include
+
+int main()
+{
+ vix::threadpool::ThreadPool pool(4);
+
+ std::vector numbers(100);
+
+ std::iota(numbers.begin(), numbers.end(), 1);
+
+ const int sum =
+ vix::threadpool::parallel_reduce(
+ pool,
+ numbers,
+ 0,
+ [](int current, int value)
+ {
+ return current + value;
+ });
+
+ std::cout << "Sum: " << sum << '\n';
+
+ pool.shutdown();
+
+ return 0;
+}
diff --git a/examples/threadpool/periodic_task.cpp b/examples/threadpool/periodic_task.cpp
new file mode 100644
index 0000000..0ae9dd0
--- /dev/null
+++ b/examples/threadpool/periodic_task.cpp
@@ -0,0 +1,63 @@
+/**
+ *
+ * @file periodic_task.cpp
+ * @author Gaspard Kirira
+ *
+ * Copyright 2025, Gaspard Kirira.
+ * All rights reserved.
+ * https://github.com/vixcpp/vix
+ *
+ * Use of this source code is governed by a MIT license
+ * that can be found in the License file.
+ *
+ * Vix.cpp
+ *
+ */
+#include
+#include
+#include
+#include
+
+#include
+
+int main()
+{
+ vix::threadpool::ThreadPool pool(2);
+
+ std::atomic ticks{0};
+
+ vix::threadpool::PeriodicTaskConfig config;
+ config.interval = std::chrono::milliseconds{100};
+ config.run_immediately = true;
+
+ vix::threadpool::PeriodicTask task(
+ pool,
+ [&ticks]()
+ {
+ const int current = ticks.fetch_add(1, std::memory_order_relaxed) + 1;
+ std::cout << "Tick: " << current << '\n';
+ },
+ config);
+
+ if (!task.start())
+ {
+ std::cout << "Failed to start periodic task\n";
+ pool.shutdown();
+ return 1;
+ }
+
+ std::this_thread::sleep_for(std::chrono::milliseconds{450});
+
+ task.stop();
+ task.join();
+
+ pool.wait_idle();
+
+ std::cout << "Submitted ticks: " << task.submitted_ticks() << '\n';
+ std::cout << "Failed posts: " << task.failed_posts() << '\n';
+ std::cout << "Observed ticks: " << ticks.load() << '\n';
+
+ pool.shutdown();
+
+ return 0;
+}
diff --git a/examples/threadpool/shutdown.cpp b/examples/threadpool/shutdown.cpp
new file mode 100644
index 0000000..1fe4fb5
--- /dev/null
+++ b/examples/threadpool/shutdown.cpp
@@ -0,0 +1,60 @@
+/**
+ *
+ * @file shutdown.cpp
+ * @author Gaspard Kirira
+ *
+ * Copyright 2025, Gaspard Kirira.
+ * All rights reserved.
+ * https://github.com/vixcpp/vix
+ *
+ * Use of this source code is governed by a MIT license
+ * that can be found in the License file.
+ *
+ * Vix.cpp
+ *
+ */
+#include
+#include
+#include
+
+#include
+
+int main()
+{
+ vix::threadpool::ThreadPool pool(2);
+
+ for (int i = 0; i < 4; ++i)
+ {
+ pool.post(
+ [i]()
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds{50});
+ std::cout << "Task finished: " << i << '\n';
+ });
+ }
+
+ pool.wait_idle();
+
+ std::cout << "Pool idle before shutdown: "
+ << (pool.idle() ? "yes" : "no")
+ << '\n';
+
+ pool.shutdown();
+
+ std::cout << "Pool running after shutdown: "
+ << (pool.running() ? "yes" : "no")
+ << '\n';
+
+ const bool accepted =
+ pool.post(
+ []()
+ {
+ std::cout << "This should not run after shutdown\n";
+ });
+
+ std::cout << "Post after shutdown accepted: "
+ << (accepted ? "yes" : "no")
+ << '\n';
+
+ return 0;
+}
diff --git a/examples/threadpool/submit_future.cpp b/examples/threadpool/submit_future.cpp
new file mode 100644
index 0000000..61b38d8
--- /dev/null
+++ b/examples/threadpool/submit_future.cpp
@@ -0,0 +1,48 @@
+/**
+ *
+ * @file submit_future.cpp
+ * @author Gaspard Kirira
+ *
+ * Copyright 2025, Gaspard Kirira.
+ * All rights reserved.
+ * https://github.com/vixcpp/vix
+ *
+ * Use of this source code is governed by a MIT license
+ * that can be found in the License file.
+ *
+ * Vix.cpp
+ *
+ */
+#include
+#include
+
+#include
+
+int main()
+{
+ vix::threadpool::ThreadPool pool(4);
+
+ auto numberFuture =
+ pool.submit(
+ []()
+ {
+ return 42;
+ });
+
+ auto textFuture =
+ pool.submit(
+ []()
+ {
+ return std::string{"Hello from Vix threadpool"};
+ });
+
+ const int number = numberFuture.get();
+ const std::string text = textFuture.get();
+
+ std::cout << "Number result: " << number << '\n';
+ std::cout << "Text result: " << text << '\n';
+
+ pool.shutdown();
+
+ return 0;
+}
diff --git a/examples/threadpool/task_cancellation.cpp b/examples/threadpool/task_cancellation.cpp
new file mode 100644
index 0000000..6cb759b
--- /dev/null
+++ b/examples/threadpool/task_cancellation.cpp
@@ -0,0 +1,57 @@
+/**
+ *
+ * @file task_cancellation.cpp
+ * @author Gaspard Kirira
+ *
+ * Copyright 2025, Gaspard Kirira.
+ * All rights reserved.
+ * https://github.com/vixcpp/vix
+ *
+ * Use of this source code is governed by a MIT license
+ * that can be found in the License file.
+ *
+ * Vix.cpp
+ *
+ */
+#include
+#include
+#include
+
+#include
+
+int main()
+{
+ vix::threadpool::ThreadPool pool(2);
+
+ auto handle =
+ pool.handle(
+ []()
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ return 7;
+ });
+
+ handle.cancel();
+
+ try
+ {
+ const int value = handle.get();
+ std::cout << "Result: " << value << '\n';
+ }
+ catch (const std::exception &e)
+ {
+ std::cout << "Task failed: " << e.what() << '\n';
+ }
+
+ std::cout << "Cancelled: "
+ << (handle.cancelled() ? "yes" : "no")
+ << '\n';
+
+ std::cout << "Task status: "
+ << vix::threadpool::to_string(handle.status())
+ << '\n';
+
+ pool.shutdown();
+
+ return 0;
+}
diff --git a/examples/threadpool/task_group.cpp b/examples/threadpool/task_group.cpp
new file mode 100644
index 0000000..d36e26c
--- /dev/null
+++ b/examples/threadpool/task_group.cpp
@@ -0,0 +1,73 @@
+/**
+ *
+ * @file task_group.cpp
+ * @author Gaspard Kirira
+ *
+ * Copyright 2025, Gaspard Kirira.
+ * All rights reserved.
+ * https://github.com/vixcpp/vix
+ *
+ * Use of this source code is governed by a MIT license
+ * that can be found in the License file.
+ *
+ * Vix.cpp
+ *
+ */
+#include
+#include
+#include
+
+#include
+
+int main()
+{
+ vix::threadpool::TaskGroup group;
+
+ group.add_task(1);
+ group.add_task(2);
+ group.add_task(3);
+
+ std::thread first(
+ [&group]()
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(20));
+
+ group.finish_task(
+ vix::threadpool::TaskStatus::completed,
+ vix::threadpool::TaskResult::success);
+ });
+
+ std::thread second(
+ [&group]()
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(40));
+
+ group.finish_task(
+ vix::threadpool::TaskStatus::completed,
+ vix::threadpool::TaskResult::success);
+ });
+
+ std::thread third(
+ [&group]()
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(60));
+
+ group.finish_task(
+ vix::threadpool::TaskStatus::cancelled,
+ vix::threadpool::TaskResult::cancelled);
+ });
+
+ group.close();
+ group.wait();
+
+ first.join();
+ second.join();
+ third.join();
+
+ std::cout << "Total tasks: " << group.total_tasks() << '\n';
+ std::cout << "Completed: " << group.completed_tasks() << '\n';
+ std::cout << "Cancelled: " << group.cancelled_tasks() << '\n';
+ std::cout << "Has error: " << (group.has_error() ? "yes" : "no") << '\n';
+
+ return 0;
+}
diff --git a/examples/threadpool/task_priority.cpp b/examples/threadpool/task_priority.cpp
new file mode 100644
index 0000000..af6a078
--- /dev/null
+++ b/examples/threadpool/task_priority.cpp
@@ -0,0 +1,73 @@
+/**
+ *
+ * @file task_priority.cpp
+ * @author Gaspard Kirira
+ *
+ * Copyright 2025, Gaspard Kirira.
+ * All rights reserved.
+ * https://github.com/vixcpp/vix
+ *
+ * Use of this source code is governed by a MIT license
+ * that can be found in the License file.
+ *
+ * Vix.cpp
+ *
+ */
+#include
+#include
+#include
+
+#include
+
+int main()
+{
+ vix::threadpool::ThreadPool pool(2);
+
+ std::mutex mutex;
+ std::vector order;
+
+ vix::threadpool::TaskOptions lowPriority;
+ lowPriority.set_priority(vix::threadpool::TaskPriority::low);
+
+ vix::threadpool::TaskOptions highPriority;
+ highPriority.set_priority(vix::threadpool::TaskPriority::high);
+
+ pool.post(
+ [&mutex, &order]()
+ {
+ std::lock_guard lock(mutex);
+ order.push_back(1);
+ },
+ lowPriority);
+
+ pool.post(
+ [&mutex, &order]()
+ {
+ std::lock_guard lock(mutex);
+ order.push_back(2);
+ },
+ highPriority);
+
+ pool.post(
+ [&mutex, &order]()
+ {
+ std::lock_guard lock(mutex);
+ order.push_back(3);
+ },
+ highPriority);
+
+ pool.wait_idle();
+
+ std::cout << "Execution order:";
+
+ for (const int value : order)
+ {
+ std::cout << ' ' << value;
+ }
+
+ std::cout << '\n';
+
+ pool.shutdown();
+
+ return 0;
+}
diff --git a/examples/threadpool/task_timeout.cpp b/examples/threadpool/task_timeout.cpp
new file mode 100644
index 0000000..2dc600c
--- /dev/null
+++ b/examples/threadpool/task_timeout.cpp
@@ -0,0 +1,59 @@
+/**
+ *
+ * @file task_timeout.cpp
+ * @author Gaspard Kirira
+ *
+ * Copyright 2025, Gaspard Kirira.
+ * All rights reserved.
+ * https://github.com/vixcpp/vix
+ *
+ * Use of this source code is governed by a MIT license
+ * that can be found in the License file.
+ *
+ * Vix.cpp
+ *
+ */
+#include
+#include
+#include
+
+#include
+
+int main()
+{
+ vix::threadpool::ThreadPool pool(2);
+
+ vix::threadpool::TaskOptions options;
+ options.set_timeout(vix::threadpool::Timeout::milliseconds(50));
+
+ auto future =
+ pool.submit(
+ []()
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ return 42;
+ },
+ options);
+
+ try
+ {
+ const int value = future.get();
+ std::cout << "Result: " << value << '\n';
+ }
+ catch (const std::exception &e)
+ {
+ std::cout << "Task failed: " << e.what() << '\n';
+ }
+
+ std::cout << "Future status: "
+ << vix::threadpool::to_string(future.status())
+ << '\n';
+
+ std::cout << "Future result: "
+ << vix::threadpool::to_string(future.result())
+ << '\n';
+
+ pool.shutdown();
+
+ return 0;
+}
diff --git a/modules/cli b/modules/cli
index 4dd47cc..43772ea 160000
--- a/modules/cli
+++ b/modules/cli
@@ -1 +1 @@
-Subproject commit 4dd47cc70cdaee45d4a1e7efe8f8732f6691a8f7
+Subproject commit 43772ea07f85a0c05c93eb91f32ea9acd2aaf24b
diff --git a/modules/core b/modules/core
index c2b3b11..382d0b9 160000
--- a/modules/core
+++ b/modules/core
@@ -1 +1 @@
-Subproject commit c2b3b11d4a98c59253bfb58bf3f8570d5b5c1f5e
+Subproject commit 382d0b9d55a8f0ff89b1d7bbecdd5827c7ba3867
|