{"record":{"id":"52bc84c659a8c4d7","repo":"stride3d/stride","slug":"globalmutex-wait-is-implemented-only-for-millisecondstimeout","errorCode":null,"errorMessage":"GlobalMutex.Wait() is implemented only for millisecondsTimeout 0 or -1","messagePattern":"GlobalMutex\\.Wait\\(\\) is implemented only for millisecondsTimeout 0 or -1","errorType":"exception","errorClass":"NotImplementedException","httpStatus":null,"severity":"error","filePath":"sources/core/Stride.Core.Design/Windows/FileLock.cs","lineNumber":87,"sourceCode":"\n    /// <summary>\n    /// Tries to take ownership of the file lock within a given delay.\n    /// </summary>\n    /// <param name=\"name\">A unique name identifying the file lock.</param>\n    /// <param name=\"millisecondsTimeout\">The maximum delay to wait before returning, in milliseconds.</param>\n    /// <returns>A new instance of <see cref=\"FileLock\"/> if the ownership could be taken, <c>null</c> otherwise.</returns>\n    /// <remarks>\n    /// The returned <see cref=\"FileLock\"/> must be disposed to release the file lock.\n    /// Calling this method with 0 for <see paramref=\"millisecondsTimeout\"/> is equivalent to call <see cref=\"TryLock\"/>.\n    /// Calling this method with a negative value for <see paramref=\"millisecondsTimeout\"/> is equivalent to call <see cref=\"Wait(string)\"/>.\n    /// </remarks>\n    public static FileLock? Wait(string name, int millisecondsTimeout)\n    {\n        var fileLock = BuildFileLock(name);\n        try\n        {\n            if (millisecondsTimeout != 0 && millisecondsTimeout != -1)\n                throw new NotImplementedException(\"GlobalMutex.Wait() is implemented only for millisecondsTimeout 0 or -1\");\n\n            bool hasHandle = NativeLockFile.TryLockFile(fileLock, 0, uint.MaxValue, true, millisecondsTimeout == 0);\n            return hasHandle ? new FileLock(fileLock) : null;\n        }\n        catch (AbandonedMutexException)\n        {\n            return new FileLock(fileLock);\n        }\n    }\n\n    private static FileStream BuildFileLock(string name)\n    {\n        // We open with FileShare.ReadWrite mode so that we can implement `Wait`.\n        return new FileStream(name, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);\n    }\n}\n","sourceCodeStart":69,"sourceCodeEnd":104,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/core/Stride.Core.Design/Windows/FileLock.cs#L69-L104","documentation":"FileLock.Wait only supports millisecondsTimeout of 0 (single try) or -1 (infinite wait) because it maps directly onto GlobalMutex.Wait semantics. Any other timeout throws NotImplementedException from the Wait method (also reachable via TryLock).","triggerScenarios":"Calling FileLock.Wait(name, timeout) with any value other than 0 or -1, e.g. Wait(\"mylock\", 5000). Also via TryLock if it forwards a non-{0,-1} timeout.","commonSituations":" Developers assuming a standard bounded-timeout locking API; migrating from Mutex.WaitOne(TimeSpan) style code; adding retry loops with finite timeouts.","solutions":["Use 0 for a single non-blocking attempt and poll in your own loop with Thread.Sleep","Use -1 to block indefinitely until the lock is acquired","Wrap the call site with your own deadline logic around repeated 0-timeout attempts","Check library version/upstream for bounded-timeout support before using other values"],"exampleFix":"// before\nvar l = FileLock.Wait(name, 5000);\n// after\nvar l = FileLock.Wait(name, -1); // or poll with 0 in your own loop","handlingStrategy":"try-catch","validationCode":"if (timeout != 0 && timeout != -1)\n    throw new InvalidOperationException(\"FileLock.Wait only supports 0 or -1\");","typeGuard":null,"tryCatchPattern":"try { l = FileLock.Wait(name, 0); }\ncatch (NotImplementedException) { /* fall back to manual polling loop */ }","preventionTips":["Only use 0 or -1 timeouts","Implement bounded waits with your own poll loop","Document this API limitation at call sites"],"tags":["file-lock","concurrency","windows","timeout"],"backgroundTag":"method-not-implemented","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}