Skip to content

Fix Windows lock file access errors - #222

Open
nygrenh wants to merge 5 commits into
mainfrom
windows-permission-denied
Open

Fix Windows lock file access errors#222
nygrenh wants to merge 5 commits into
mainfrom
windows-permission-denied

Conversation

@nygrenh

@nygrenh nygrenh commented Aug 5, 2026

Copy link
Copy Markdown
Member

No description provided.

@nygrenh
nygrenh force-pushed the windows-permission-denied branch 2 times, most recently from 8be76f6 to ad3e5d1 Compare August 5, 2026 13:21
nygrenh added 4 commits August 6, 2026 08:32
Deleting per-directory .tmc.lock files raced concurrent processes on
Windows: delete-on-close puts the file into delete-pending, and every
other open then fails with ERROR_ACCESS_DENIED until the last handle
closes. Every submit runs tests and checkstyle concurrently, so this
window opened on every submission.

Directory locks now use a persistent lock file in a client-independent
locks dir (env override -> local data dir -> temp dir), keyed by a
hashed stable path so the key matches before and after the directory
exists. The OS releases the lock on process death.

Also retry transient open errors, truncate files only after their lock
is held, fix the unix no-lock fallback (always failed with EISDIR),
lock extract-project's output dir, isolate test lock dirs, and drop
dead ReadTruncate/forget() code and the winapi dependency.
Install Ant on the Windows runner: the ant plugin shells out to ant.bat,
which that image doesn't ship, so every ant test failed with "could not be
found".

Stop asserting the exact hash of a compressed project. It varies between
platforms and between runs, which is why the compress tests are already
skipped on Windows; snapshot that a hash was produced instead of which one.

Update the expected dynamic library counts to what the current toolchain and
runner images link. Building the CLI from this branch and from main with the
same toolchain gives byte-identical library sets, so nothing here added one.
@nygrenh
nygrenh force-pushed the windows-permission-denied branch from ad3e5d1 to fd01076 Compare August 6, 2026 05:33
Derive the whole lock file name from the normalized key rather than the raw
path. sanitized_suffix used Path::file_name on the argument, which is None for
"." and for a ".."-terminated path but Some for the equivalent absolute path,
so two spellings of one directory took two different locks and excluded
nothing.

Key the temp-dir fallback per OS user and restrict it to 0700. It landed in
the world-shared /tmp, where the first user to create a lock file owned one
that the next user could not open, failing every directory lock.

Replace the unsafe set_var in the test helpers with an in-process override.
Only some of the tests in each binary called the helper, so the write raced
the environment reads of every test already running.

Shard the locks dir by hash prefix and sweep entries older than 30 days,
taking each exclusively before removing it. Nothing pruned them, so the dir
grew one permanent file per directory ever locked.

Log an escalating warning while a Windows lock wait is outstanding. The old
escalating messages went away with the polling loop, leaving an indefinite
wait with nothing in the log support asks for.

Bound transient open retries per process as well as per lock, so a
permanently unwritable locks dir fails instead of stalling a command that
locks several directories, and give Lock::file the same retry as Lock::dir.

Share one truncate-after-lock helper between the platforms. The two copies had
drifted: the Windows one reported the locked directory as the path it failed
to write.

Create the central lock file in lock() and propagate the failure, instead of
pre-creating it in dir() and discarding both the handle and the error.

Always use the bundled Maven. Fixing ExitStatus::success made the PATH probe
live, silently switching Maven exercises to whatever mvn a student happens to
have installed.

Narrow the insta hash filter to the compressed-project-hash field, add a test
that one input compresses to one hash, and cover the default locks dir
resolution, which no test reached.
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.

1 participant