{"record":{"id":"2fa3ac702155c4c2","repo":"java-native-access/jna","slug":"win32exception-from-native-getlasterror-after-2fa3ac","errorCode":null,"errorMessage":"Win32Exception from native GetLastError after SetThreadPriority (background mode) failed","messagePattern":"Win32Exception from native GetLastError after SetThreadPriority \\(background mode\\) failed","errorType":"error_code","errorClass":"Win32Exception","httpStatus":null,"severity":"error","filePath":"contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java","lineNumber":1343,"sourceCode":"        if (!isValidThreadPriority(nPriority)) {\n            throw new IllegalArgumentException(\"The given priority value is invalid!\");\n        }\n        if (!Kernel32.INSTANCE.SetThreadPriority(Kernel32.INSTANCE.GetCurrentThread(), nPriority)) {\n            throw new Win32Exception(Kernel32.INSTANCE.GetLastError());\n        }\n    }\n\n    /**\n     * Enables or disables \"background\" processing mode for the current thread\n     *\n     * @param enable If true, enables \"background\" processing mode, otherwise disables it.\n     * @throws Win32Exception if an error occurs.\n     */\n    public static void setCurrentThreadBackgroundMode(final boolean enable) {\n        // Note: THREAD_MODE_BACKGROUND_{BEGIN,END} only works with the \"current\" thread handle!\n        final int nPriority = enable ? Kernel32.THREAD_MODE_BACKGROUND_BEGIN : Kernel32.THREAD_MODE_BACKGROUND_END;\n        if (!Kernel32.INSTANCE.SetThreadPriority(Kernel32.INSTANCE.GetCurrentThread(), nPriority)) {\n            throw new Win32Exception(Kernel32.INSTANCE.GetLastError());\n        }\n    }\n\n    /**\n     * Gets the priority class of the specified process.\n     *\n     * @param pid Identifier for the running process.\n     * @throws Win32Exception if an error occurs.\n     */\n    public static DWORD getProcessPriority(final int pid) {\n        final HANDLE hProcess = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_QUERY_INFORMATION , false, pid);\n        if (hProcess == null) {\n            throw new Win32Exception(Kernel32.INSTANCE.GetLastError());\n        }\n\n        Win32Exception we = null;\n        try {\n            final DWORD dwPriorityClass = Kernel32.INSTANCE.GetPriorityClass(hProcess);","sourceCodeStart":1325,"sourceCodeEnd":1361,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java#L1325-L1361","documentation":"setCurrentThreadBackgroundMode(boolean) maps 'enable' to THREAD_MODE_BACKGROUND_BEGIN or THREAD_MODE_BACKGROUND_END and calls SetThreadPriority on the current thread. If the native call fails, the library throws a Win32Exception from GetLastError(). Background-begin requires an elevated context and background-end fails if background mode was never started.","triggerScenarios":"Calling Kernel32Util.setCurrentThreadBackgroundMode(true) from a non-elevated thread (needs privilege), or setCurrentThreadBackgroundMode(false) when background mode was never enabled — SetPriorityClass-style native failure propagates as Win32Exception.","commonSituations":"Unbalanced begin/end pairs across worker threads (background mode is per-thread); non-admin processes attempting to lower their I/O priority; Windows editions or job objects that reject background mode.","solutions":["Pair every setCurrentThreadBackgroundMode(true) with a matching (false) in a finally block, on the same thread.","Run elevated when enabling background mode since it requires additional privilege.","Check Win32Exception.getErrorCode(): ERROR_PROCESS_MODE_ALREADY_BACKGROUND / NOT_BACKGROUND indicate unbalanced begin/end calls.","Fall back to SetThreadPriority(THREAD_PRIORITY_LOWEST) or SetThreadInformation thread I/O priority if background mode is unavailable."],"exampleFix":"// before\nKernel32Util.setCurrentThreadBackgroundMode(true);\ndoIoHeavyWork();\nKernel32Util.setCurrentThreadBackgroundMode(false);\n// after\nboolean bg = false;\ntry {\n    Kernel32Util.setCurrentThreadBackgroundMode(true);\n    bg = true;\n    doIoHeavyWork();\n} finally {\n    if (bg) Kernel32Util.setCurrentThreadBackgroundMode(false);\n}","handlingStrategy":"try-catch","validationCode":"// track per-thread state to keep begin/end balanced:\nif (enable && BACKGROUND_ACTIVE.get()) { throw new IllegalStateException(\"background mode already active\"); }\nif (!enable && !BACKGROUND_ACTIVE.get()) { return; }","typeGuard":null,"tryCatchPattern":"try {\n    Kernel32Util.setCurrentThreadBackgroundMode(true);\n    BACKGROUND_ACTIVE.set(true);\n} catch (Win32Exception e) {\n    log.warn(\"Thread background mode failed: {}\", e.getErrorCode());\n} finally {\n    if (BACKGROUND_ACTIVE.get()) {\n        Kernel32Util.setCurrentThreadBackgroundMode(false);\n        BACKGROUND_ACTIVE.set(false);\n    }\n}","preventionTips":["Background mode is per-thread: begin and end must run on the same thread — use ThreadLocal state.","Put the 'end' call in a finally block to keep pairs balanced across exceptions.","Require elevation for THREAD_MODE_BACKGROUND_BEGIN.","Fall back to THREAD_PRIORITY_LOWEST when background mode is unavailable."],"tags":["win32","jna","windows","background-mode","thread-priority"],"backgroundTag":"permission-denied","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}