Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ These paths run at 60 fps or more from game callbacks. `[B-02]` governs allocati

- `detail::InputPoller::is_binding_active(index/name/token)` uses a `shared_lock` and a relaxed load.
- The `Logger::log()` level check and `is_enabled()` use one atomic load.
- The formatted `Logger::log()` stamp check uses one relaxed atomic load after the level check.
- The `Logger::log()` asynchronous enqueue uses an atomic shared-pointer snapshot and a lock-free queue push. The snapshot uses a bounded internal lock.
- `memory::is_readable(Region)` uses a sharded SRWLOCK reader and a cache lookup.
- `memory::is_readable_nonblocking(Region)` uses a shared try-lock and a cache lookup. It returns `Unknown` after contention or an unpublished cache result.
Expand Down Expand Up @@ -498,7 +499,7 @@ A same-ID design-note pointer owns the complete rationale for that rule. A gener
- `[B-10]` `[CONVENTION]` **Generated build artifacts must not enter commits.** [docs/design/build-ci.md](docs/design/build-ci.md) supplies related evidence.
- `[B-11]` `[CONVENTION]` **A change must not remove or weaken current tests.** New code must have new tests. [docs/design/testing.md](docs/design/testing.md) supplies the test policy.
- `[B-12]` `[CONVENTION]` **Top-level public API must not expose implementation-only container or entry types.** Such types must remain in `namespace detail` or an internal header. A backend type must stay behind a forward-declared `Impl`. [docs/design/public-api.md](docs/design/public-api.md) `[B-12]` owns the rationale.
- `[B-13]` `[CONVENTION]` **If one listed trigger applies, a public function must use a request or options struct.** The struct must default-initialize its fields for designated initialization. Each new field must follow all established fields. [docs/design/public-api.md](docs/design/public-api.md) `[B-13]` owns the rationale. The triggers are adjacent parameters of the same type, more than about five parameters, or at least three counted knobs. Optional, policy, and configuration knobs all contribute to the count.
- `[B-13]` `[CONVENTION]` **If one listed trigger applies, a public function must use a request or options struct.** The struct must default-initialize its fields for designated initialization. Each new field must follow all established fields. [docs/design/public-api.md](docs/design/public-api.md) `[B-13]` owns the rationale. The triggers are adjacent parameters of the same type, more than about five parameters, or at least three counted knobs. Optional, policy, and configuration knobs all contribute to the count. One settled exception preserves the existing `Logger` constructor and `configure` surface. `source_stamp_mode` remains a trailing defaulted parameter.
- `[B-14]` `[CONVENTION]` **Output code must use `'\n'` instead of `std::endl`.** `std::endl` forces a flush. [docs/design/build-ci.md](docs/design/build-ci.md) supplies related evidence.
- `[B-15]` `[SAFETY]` **Hook callbacks must use `EventDispatcher::emit_safe()`.** It contains handler exceptions. `EventDispatcherTest.EmitSafe_CatchesHandlerExceptions` proves the contract.
- `[B-16]` `[SAFETY]` **Teardown must destroy layered hooks on one target newest-first.** `hook::HookStack` enforces this order. [docs/design/hooking.md](docs/design/hooking.md) `[B-16]` owns the rationale.
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.28)

project(DetourModKit VERSION 4.1.1 LANGUAGES CXX)
project(DetourModKit VERSION 4.2.0 LANGUAGES CXX)

# DetourModKit patches native x86-64 Windows processes. Another target fails before platform-specific checks cascade.
# The public header and installed package enforce the same target contract.
Expand Down
2 changes: 2 additions & 0 deletions docs/design/logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Async reads use an `atomic<shared_ptr>` snapshot. The snapshot takes a bounded i

Hot-path mechanism: The `log()` level check costs one atomic load.

Formatted records apply one `LogSourceStampMode` policy. `always()` retains every stamp. `at_or_below(level)` retains stamps from Trace through that level. `never()` removes every stamp. The default uses `at_or_below(Debug)`, so the default Info admission produces no stamped records. The policy does not change record admission or the raw record tier. Each formatted path reads one relaxed atomic value before line format.

### AsyncLogger

The queue is a lock-free Vyukov-style MPMC queue. Shutdown has a single owner: admitted producers finish, later producers drop and count, and the writer alone drains and acknowledges completion.
Expand Down
2 changes: 2 additions & 0 deletions docs/design/public-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ The two standing high-arity idioms are deliberately mitigated and are the patter

Reach for the struct form on every new public entry point.

The existing `Logger` constructor and `configure` form one settled exception. Their `source_stamp_mode` parameter stays trailing and defaulted for ordinary call compatibility.

### [B-69]

`error.hpp` documents that `SystemCallFailed`'s `detail` carries `GetLastError()`, and `detail::acquire_module_ref` restores the thread's last-error on failure precisely so its caller can read it. A failure site that builds `Error{SystemCallFailed, where}` with no detail leaves the consumer with a read of 0.
Expand Down
Loading
Loading