Skip to content

Fix Windows write support (issue #1005)#1159

Open
riverdusty wants to merge 1 commit into
ApptiveGrid:mainfrom
riverdusty:fix-1005-windows-writes
Open

Fix Windows write support (issue #1005)#1159
riverdusty wants to merge 1 commit into
ApptiveGrid:mainfrom
riverdusty:fix-1005-windows-writes

Conversation

@riverdusty

@riverdusty riverdusty commented Jun 17, 2026

Copy link
Copy Markdown

Why

Soil could not be opened or written on Windows. Reproducing on a live Pharo image revealed three layered blockers, each only reachable after fixing the prior one:

  1. fsyncBinaryFileStream>>fsync called POSIX fileno/fsync (absent on Windows, giving SymbolNotFoundError on msvcrt).
  2. File lockingOSPlatform>>flockClass had no Windows implementation.
  3. Multiple file open (Windows Compatibility Issue: SoilLockableStream Multiple File Open Problem #1005) — the same path was opened in write mode from a second stream, which Windows rejects with CannotDeleteFileException.

Fixes #1005.

What changed

Windows prerequisites (1 & 2) — ported from the unmerged integrate-windows-locking branch (those Soil-File files were unchanged on main since the merge-base, so taken as-is):

  • SoilWindowsFileLock (LockFileEx/UnlockFileEx + FlushFileBuffers), SoilWinOverlappedStruct, WinPlatform lock/sync
  • BinaryFileStream>>fsync now delegates to OSPlatform>>syncFile:; fileno:/fsync:/syncFile: moved onto the platform classes
  • lock classes renamed UnixFileLock/MacOSFileLock to SoilUnixFileLock/SoilMacOSFileLock

Issue #1005 — read-only opens / single write-owner per path:

  • New read-only stream support: SoilLockableStream class>>readOnlyPath: + FileReference>>binaryReadOnlyStream (in-image locking only — a read-only handle cannot hold an OS write lock, and these reads are of a consistent snapshot)
  • Journal recovery, journal query/replication (transactionJournalsStartingAt:do:), and the read-only journal visitor (SoilBasicVisitor>>visitJournalFragmentFile:) now open fragment files read-only and close them
  • Recovery closes its read-only handle before the journal reopens the file for writing; cycleFragmentFileFrom: cycles from a read-only recovery file without flushing/syncing it
  • Backup reuses the already-open behavior-registry identifier index instead of opening the same file a second time
  • Index commit (SoilNewSkipListIndexEntry/SoilNewBTreeListIndexEntry>>commitIn:) reuses an already-open index instead of re-initializeFilesystem

Verification

Verified end-to-end on Windows (Pharo image): create -> write -> close -> reopen -> write -> reopen -> read round-trips with data intact. Suites green: SoilBackupTest (7/7), SoilDatabaseJournalTest incl. replication (9/9), SoilTransactionTest (9/9); testCheckpointEmptyRecordsToCommit and testConsistency pass.

Notes for reviewers

  • Non-Windows behavior is unchanged: the new code paths only switch read-only callers to read-only opens and reuse already-open handles.
  • Known follow-up (not in this PR): the full test suite on Windows still shows cascading failures from test-isolation pollution — a test leaks a file handle and a later test's destroy then hits CannotDeleteFileException. Every such test passes when run individually. SoilLockableStreamTest also has a pre-existing, unrelated Windows path bug.

Generated with Claude Code

Soil could not be opened or written on Windows. Reproducing on a live Pharo
image revealed three layered blockers, each only reachable after fixing the
prior one:

1. fsync: BinaryFileStream>>fsync used POSIX fileno/fsync (absent on Windows).
2. file locking: OSPlatform had no Windows flock implementation.
3. multiple file open (ApptiveGrid#1005): the same path was opened in write mode from a
   second stream, which Windows rejects.

Windows prerequisites (1 & 2) are ported from the unmerged
integrate-windows-locking branch (those Soil-File files were unchanged on main
since the merge-base): SoilWindowsFileLock (LockFileEx/UnlockFileEx +
FlushFileBuffers), SoilWinOverlappedStruct, WinPlatform sync/lock, platform
syncFile: dispatch in BinaryFileStream, and the Soil*FileLock renames.

For ApptiveGrid#1005, add read-only stream support and route read-only file access through
it so a path only ever has one write-mode handle:
- SoilLockableStream readOnlyPath: / FileReference binaryReadOnlyStream
  (in-image locking only; a read-only handle cannot hold an OS write lock).
- Journal recovery, journal query/replication
  (transactionJournalsStartingAt:do:), and the read-only journal visitor
  (SoilBasicVisitor>>visitJournalFragmentFile:) now open fragment files
  read-only and close them.
- Recovery closes its read-only handle before the journal reopens for writing;
  cycleFragmentFileFrom: cycles from a read-only recovery file without flushing.
- Backup reuses the already-open behavior-registry identifier index instead of
  reopening the same file.
- Index commit (SoilNew{SkipList,BTree}IndexEntry>>commitIn:) reuses an
  already-open index instead of re-initializing it.

Verified on Windows: create/write/close/reopen/write round-trip works;
SoilBackupTest, SoilDatabaseJournalTest (incl. replication) and
SoilTransactionTest pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

Windows Compatibility Issue: SoilLockableStream Multiple File Open Problem

1 participant