Skip to content

Conversation

@pknowles
Copy link
Contributor

@pknowles pknowles commented Aug 3, 2025

Add writable_file::sync() and resizable_file::sync() with optional
offset and size arguments

Drive-by fix for likely outdated NtQuerySection definition

Removed unused ntifs() dll module singleton

Renamed SectionPageProtection that used to shadow a createSection()
parameter

Fix writable_file mapping permissions. Was outright missing write permissions on windows and private/non-shared
on linux.

Summary by CodeRabbit

  • New Features

    • Added explicit synchronization methods for memory-mapped files, allowing users to flush changes to disk either for the entire file or for a specific range, on both Linux and Windows.
    • Introduced new C++ concepts to validate the interface of writable and resizable mapped file types.
  • Bug Fixes

    • Improved type correctness and pointer arithmetic for better compatibility and reliability on Windows.
  • Documentation

    • Enhanced README with clearer descriptions, updated usage examples, and detailed build instructions.
  • Tests

    • Added tests to verify writable memory mapping and explicit synchronization of file changes.
  • Chores

    • Updated copyright year to 2024-2025.
    • Improved code comments for clarity.

@coderabbitai
Copy link

coderabbitai bot commented Aug 3, 2025

Walkthrough

This update introduces explicit synchronization and flushing capabilities for memory-mapped files on both Linux and Windows platforms. New sync (Linux) and sync/flush (Windows) methods are added to mapped file classes, enabling both full and partial range synchronization. Concepts and tests are updated to verify these capabilities. Documentation and copyright years are refreshed.

Changes

Cohort / File(s) Change Summary
Linux Mapped File Synchronization
include/decodeless/detail/mappedfile_linux.hpp
Adds sync() and sync(offset, size) methods for writable memory-mapped files, aligns sync operations to page boundaries, removes external mapping flags, and propagates sync to higher-level abstractions.
Windows Mapped File Flushing
include/decodeless/detail/mappedfile_windows.hpp
Adds flush() and flush(offset, bytes) methods for file handles and views, introduces NT API flush support, updates pointer arithmetic and NT API types, and propagates sync methods through mapped file classes.
Mapped File Concepts
include/decodeless/mappedfile.hpp
Expands concepts to require both sync() and sync(offset, size) methods for writable and resizable mapped files; updates static assertions.
Tests for Synchronization
test/src/mappedfile.cpp
Adds tests for writable mapping, explicit synchronization, and resizable file sync; minor code modernizations and copyright update.
Documentation and Copyright
README.md, CMakeLists.txt
Updates documentation for clarity, adds build instructions, increases example mapped file size, and updates copyright years.

Sequence Diagram(s)

Memory-Mapped File Synchronization (Generic Flow)

sequenceDiagram
    participant User
    participant MappedFile
    participant OS

    User->>MappedFile: sync(offset, size)
    MappedFile->>OS: msync/FlushViewOfFile(offset, size)
    OS-->>MappedFile: Success/Error
    MappedFile-->>User: Return/Throw
Loading

Resizable Mapped File Synchronization

sequenceDiagram
    participant User
    participant ResizableMappedFile
    participant UnderlyingMappedFile
    participant OS

    User->>ResizableMappedFile: sync(offset, size)
    ResizableMappedFile->>UnderlyingMappedFile: sync(offset, size)
    UnderlyingMappedFile->>OS: msync/FlushViewOfFile(offset, size)
    OS-->>UnderlyingMappedFile: Success/Error
    UnderlyingMappedFile-->>ResizableMappedFile: Return/Throw
    ResizableMappedFile-->>User: Return/Throw
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Poem

In the warren where bytes do hop,
Now every mapped file can flush and sync nonstop.
From Linux to Windows, the changes are neat,
Ensuring your data lands safe and complete.
With concepts and tests, our work is robust—
This bunny’s proud of code you can trust! 🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 65eaa65 and d2b9b43.

📒 Files selected for processing (6)
  • CMakeLists.txt (1 hunks)
  • README.md (3 hunks)
  • include/decodeless/detail/mappedfile_linux.hpp (4 hunks)
  • include/decodeless/detail/mappedfile_windows.hpp (18 hunks)
  • include/decodeless/mappedfile.hpp (4 hunks)
  • test/src/mappedfile.cpp (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
include/decodeless/detail/mappedfile_linux.hpp (1)
include/decodeless/detail/mappedfile_windows.hpp (23)
  • offset (167-171)
  • offset (167-167)
  • offset (196-202)
  • offset (196-197)
  • offset (565-570)
  • offset (565-565)
  • offset (571-582)
  • offset (571-572)
  • offset (665-671)
  • offset (665-665)
  • size (643-658)
  • size (643-643)
  • size (694-711)
  • size (694-694)
  • m_size (189-189)
  • m_size (487-487)
  • m_size (691-691)
  • m_size (692-692)
  • m_address (161-161)
  • m_address (434-434)
  • m_address (444-450)
  • m_address (564-564)
  • LastError (48-49)
include/decodeless/detail/mappedfile_windows.hpp (1)
include/decodeless/detail/mappedfile_linux.hpp (41)
  • LastError (30-31)
  • m_address (127-127)
  • m_address (165-182)
  • offset (128-130)
  • offset (128-128)
  • offset (132-142)
  • offset (132-133)
  • offset (208-212)
  • offset (208-209)
  • offset (247-250)
  • offset (247-247)
  • static_cast (75-75)
  • m_size (131-131)
  • m_size (289-289)
  • m_size (290-290)
  • other (56-56)
  • other (56-56)
  • other (57-63)
  • other (57-57)
  • other (113-113)
  • other (113-113)
  • other (114-122)
  • other (114-114)
  • other (232-232)
  • other (232-232)
  • other (253-258)
  • other (253-253)
  • other (288-288)
  • other (288-288)
  • other (325-325)
  • other (325-325)
  • size (76-79)
  • size (76-76)
  • size (153-162)
  • size (153-153)
  • size (236-242)
  • size (236-236)
  • size (261-265)
  • size (261-261)
  • size (292-323)
  • size (292-292)
include/decodeless/mappedfile.hpp (1)
include/decodeless/detail/mappedfile_common.hpp (1)
  • decodeless (9-24)
🪛 LanguageTool
README.md

[grammar] ~5-~5: Use correct spacing
Context: ... Components can be used individually or combined. decodeless_mappedfile is a small cross platform file mapping ...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~7-~7: Use hyphens correctly
Context: ...ed. decodeless_mappedfile is a small cross platform file mapping abstraction. It pr...

(QB_NEW_EN_OTHER_ERROR_IDS_29)


[grammar] ~64-~64: There might be a mistake here.
Context: ...library with CMake integration. Use any of: - cmake add_subdirectory(path/to/mappedfile) - cmake include(FetchContent) FetchContent_Declare( decodeless_mappedfile GIT_REPOSITORY https://github.com/decodeless/mappedfile.git GIT_TAG release_tag GIT_SHALLOW TRUE ) FetchContent_MakeAvailable(decodeless_mappedfile) - cmake find_package(decodeless_mappedfile REQUIRED CONFIG PATHS paths/to/search) Then, ```cmake targ...

(QB_NEW_EN_OTHER)

🔇 Additional comments (20)
CMakeLists.txt (1)

1-1: LGTM!

Copyright year update to include 2025.

README.md (1)

46-46: Good improvement to the example!

Changing the reserved virtual address space from 4KB to 1GB better demonstrates the library's capability to reserve large address spaces efficiently.

include/decodeless/mappedfile.hpp (3)

1-1: LGTM!

Copyright year update.


21-24: Good documentation improvement!

The expanded comment clearly explains that the types come from platform-specific implementations and that the concepts verify a common interface.


46-47: Well-designed concept updates for synchronization interface!

The changes properly enforce the new synchronization interface:

  • writable_mapped_file now requires both sync() and sync(offset, size) methods
  • New resizable_mapped_file concept combines resizable functionality with sync requirements
  • Static assertion updated to check the stronger concept

This ensures cross-platform consistency for the flush/sync capabilities introduced in this PR.

Also applies to: 58-62, 66-66

test/src/mappedfile.cpp (3)

1-1: LGTM!

Copyright year update.


29-29: Good type safety improvement!

Using static_cast instead of reinterpret_cast for void pointer conversions is more appropriate and type-safe.


32-59: Comprehensive test coverage for new sync functionality!

The new tests properly exercise the synchronization capabilities:

  • Writable: Verifies basic writable mapping functionality
  • WritableSync: Tests the sync() method (with appropriate comment about limitations)
  • ResizableFileSync: Tests both sync(offset, size) and sync() methods with various sizes

The tests provide good coverage of the new sync interface requirements.

Also applies to: 437-457

include/decodeless/detail/mappedfile_linux.hpp (4)

1-1: LGTM!

Copyright year update and header reorganization.

Also applies to: 5-5, 11-11


132-152: Well-implemented synchronization methods!

The sync methods are properly implemented:

  • Correct page alignment for msync requirements
  • Appropriate use of MS_SYNC | MS_INVALIDATE flags for synchronous flush
  • Proper bounds checking with assert
  • Consistent error handling

The page alignment calculation correctly ensures the entire requested range is synchronized.


197-199: Constructor simplification removes flexibility.

The removal of the mapFlags parameter simplifies the interface by automatically choosing MAP_SHARED for writable and MAP_PRIVATE for read-only mappings. While this is a sensible default, it removes the ability to create private writable mappings or shared read-only mappings.

Consider whether this loss of flexibility is acceptable for your use cases.


203-212: Sync methods properly delegate to MemoryMap!

The sync methods in both MappedFile and ResizableMappedFile correctly forward to the underlying MemoryMap implementation, maintaining consistency across the abstraction layers.

Also applies to: 243-250

include/decodeless/detail/mappedfile_windows.hpp (8)

107-110: LGTM!

The flush() method correctly uses FlushFileBuffers to ensure file data is written to disk, with appropriate error handling.


164-171: LGTM!

The changes correctly implement view flushing using FlushViewOfFile with proper pointer arithmetic and error handling.


186-202: LGTM!

The changes correctly:

  1. Fix the permissions issue by adding write access for writable mappings
  2. Implement proper two-phase synchronization with view flushing followed by file buffer flushing
  3. Constrain sync methods to writable mappings only

268-343: LGTM!

The NT API type definitions are correctly updated for 64-bit compatibility:

  • Added IO_STATUS_BLOCK structure needed for NtFlushVirtualMemory
  • Updated buffer size parameters from ULONG to SIZE_T for proper 64-bit support

360-378: LGTM!

The NtFlushVirtualMemory function pointer is correctly loaded from ntdll.dll and exposed as a public member.


430-452: LGTM!

Good improvements:

  • Documented suppression of warning 6250 as the intentional behavior
  • Improved pointer arithmetic using static_cast with std::byte* for better type safety

471-512: LGTM!

The changes improve flexibility by templating on PageProtection and maintain consistency with 64-bit type updates.


659-671: LGTM!

The sync methods correctly implement two-phase flushing with proper null checks and bounds validation.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch pknowles/sync

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Base automatically changed from pknowles/virtual_alloc to main August 3, 2025 22:34
Was outright missing write permissions on windows and private/non-shared
on linux.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 977ad2a and 65eaa65.

📒 Files selected for processing (6)
  • CMakeLists.txt (1 hunks)
  • README.md (3 hunks)
  • include/decodeless/detail/mappedfile_linux.hpp (4 hunks)
  • include/decodeless/detail/mappedfile_windows.hpp (18 hunks)
  • include/decodeless/mappedfile.hpp (4 hunks)
  • test/src/mappedfile.cpp (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
README.md (1)
include/decodeless/detail/mappedfile_common.hpp (1)
  • decodeless (9-24)
include/decodeless/detail/mappedfile_linux.hpp (1)
include/decodeless/detail/mappedfile_windows.hpp (23)
  • offset (167-171)
  • offset (167-167)
  • offset (196-202)
  • offset (196-197)
  • offset (565-570)
  • offset (565-565)
  • offset (571-582)
  • offset (571-572)
  • offset (665-671)
  • offset (665-665)
  • size (643-658)
  • size (643-643)
  • size (694-711)
  • size (694-694)
  • m_size (189-189)
  • m_size (487-487)
  • m_size (691-691)
  • m_size (692-692)
  • m_address (161-161)
  • m_address (434-434)
  • m_address (444-450)
  • m_address (564-564)
  • LastError (48-49)
include/decodeless/mappedfile.hpp (1)
include/decodeless/detail/mappedfile_common.hpp (1)
  • decodeless (9-24)
include/decodeless/detail/mappedfile_windows.hpp (1)
include/decodeless/detail/mappedfile_linux.hpp (41)
  • LastError (30-31)
  • m_address (127-127)
  • m_address (165-182)
  • offset (128-130)
  • offset (128-128)
  • offset (132-142)
  • offset (132-133)
  • offset (208-212)
  • offset (208-209)
  • offset (248-252)
  • offset (248-248)
  • static_cast (75-75)
  • m_size (131-131)
  • m_size (291-291)
  • m_size (292-292)
  • other (56-56)
  • other (56-56)
  • other (57-63)
  • other (57-57)
  • other (113-113)
  • other (113-113)
  • other (114-122)
  • other (114-114)
  • other (232-232)
  • other (232-232)
  • other (255-260)
  • other (255-255)
  • other (290-290)
  • other (290-290)
  • other (327-327)
  • other (327-327)
  • size (76-79)
  • size (76-76)
  • size (153-162)
  • size (153-153)
  • size (236-242)
  • size (236-236)
  • size (263-267)
  • size (263-263)
  • size (294-325)
  • size (294-294)
🪛 LanguageTool
README.md

[grammar] ~5-~5: Use correct spacing
Context: ... Components can be used individually or combined. decodeless_mappedfile is a small cross platform file mapping ...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~7-~7: Use hyphens correctly
Context: ...ed. decodeless_mappedfile is a small cross platform file mapping abstraction. It pr...

(QB_NEW_EN_OTHER_ERROR_IDS_29)


[grammar] ~10-~10: Use articles correctly
Context: ... and growing a file mapping into it for really convenient way to write binary files. ...

(QB_NEW_EN_OTHER_ERROR_IDS_11)


[grammar] ~64-~64: There might be a mistake here.
Context: ...library with CMake integration. Use any of: - add_subdirectory(path/to/mappedfile) - include(FetchContent) FetchContent_Declare( decodeless_mappedfile GIT_REPOSITORY https://github.com/decodeless/mappedfile.git GIT_TAG release_tag GIT_SHALLOW TRUE ) FetchContent_MakeAvailable(decodeless_mappedfile) - find_package(decodeless_mappedfile REQUIRED CONFIG PATHS ...) Then, ``` target_li...

(QB_NEW_EN_OTHER)

🪛 markdownlint-cli2 (0.17.2)
README.md

66-66: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


70-70: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


81-81: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


87-87: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build (windows-latest, Release, cl)
🔇 Additional comments (13)
CMakeLists.txt (1)

1-1: Copyright-year refresh acknowledged

Header update is accurate and introduces no functional impact.

README.md (1)

46-46: Good example size update.

The increase from 4096 bytes to 1 GiB better demonstrates the capability of reserving large virtual address spaces without immediate physical memory allocation.

test/src/mappedfile.cpp (2)

29-29: Good use of static_cast over reinterpret_cast.

Using static_cast for void* conversions is safer and more appropriate than reinterpret_cast.


32-58: Well-structured tests for writable mappings and sync functionality.

The new tests appropriately cover the writable mapping and sync features. The comments acknowledging the limitations of testing sync operations (since reading from the same process accesses cached pages) show good awareness of the testing constraints.

Also applies to: 437-457

include/decodeless/mappedfile.hpp (2)

42-48: Good addition of sync requirements to writable_mapped_file concept.

The addition of both sync() overloads ensures a consistent interface across platforms for flushing writable mapped files to disk.


58-66: Well-designed resizable_mapped_file concept.

The new concept appropriately combines memory resizing capabilities with synchronization requirements, ensuring resizable files can be explicitly flushed to disk.

include/decodeless/detail/mappedfile_linux.hpp (3)

132-142: Correct implementation of range-based sync.

The method properly handles page alignment requirements for msync and includes appropriate bounds checking with the assert.


197-199: Good simplification of mapping flags.

Removing the mapFlags parameter and automatically selecting MAP_SHARED for writable and MAP_PRIVATE for read-only mappings simplifies the API while maintaining correct behavior.


243-252: Appropriate sync implementation for ResizableMappedFile.

The conditional sync calls correctly handle the case where the file hasn't been mapped yet (size is 0).

include/decodeless/detail/mappedfile_windows.hpp (4)

107-110: Correct implementation of file buffer flushing.

Using FlushFileBuffers is the appropriate Windows API for ensuring file metadata and buffers are written to disk.


167-171: Proper implementation of view flushing.

The method correctly uses FlushViewOfFile with appropriate pointer arithmetic for the offset.


186-202: Well-designed sync implementation for mapped files.

The simplified protection flags align with the Linux implementation. The sync methods correctly flush the view first (asynchronously) then the file handle (synchronously with metadata), ensuring complete persistence.


659-671: Consistent sync implementation for ResizableMappedFile.

The sync methods appropriately handle the optional view and follow the same pattern as MappedFile (flush view, then file metadata).

add writable_file::sync() and resizable_file::sync() with optional
offset and size arguments

drive-by fix for likely outdated NtQuerySection definition

removed unused ntifs() dll module singleton

renamed SectionPageProtection that used to shadow a createSection()
parameter
@pknowles pknowles merged commit d2b9b43 into main Aug 4, 2025
12 checks passed
@pknowles pknowles deleted the pknowles/sync branch August 4, 2025 01:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants