diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java index 14a1bd772..2034fb143 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java @@ -68,6 +68,40 @@ public interface Kernel32 extends StdCallLibrary, WinNT, Wincon { */ int LOAD_LIBRARY_AS_DATAFILE = 0x2; + /** + * Process priority classes + */ + DWORD NORMAL_PRIORITY_CLASS = new DWORD(0x00000020L); + DWORD IDLE_PRIORITY_CLASS = new DWORD(0x00000040L); + DWORD HIGH_PRIORITY_CLASS = new DWORD(0x00000080L); + DWORD REALTIME_PRIORITY_CLASS = new DWORD(0x00000100L); + DWORD BELOW_NORMAL_PRIORITY_CLASS = new DWORD(0x00004000L); + DWORD ABOVE_NORMAL_PRIORITY_CLASS = new DWORD(0x00008000L); + DWORD PROCESS_MODE_BACKGROUND_BEGIN = new DWORD(0x00100000L); + DWORD PROCESS_MODE_BACKGROUND_END = new DWORD(0x00200000L); + + /** + * Thread priorities + */ + int THREAD_PRIORITY_IDLE = -15; + int THREAD_PRIORITY_LOWEST = -2; + int THREAD_PRIORITY_BELOW_NORMAL = -1; + int THREAD_PRIORITY_NORMAL = 0; + int THREAD_PRIORITY_ABOVE_NORMAL = 1; + int THREAD_PRIORITY_HIGHEST = 2; + int THREAD_PRIORITY_TIME_CRITICAL = 15; + + /** + * Thread mode flags + */ + int THREAD_MODE_BACKGROUND_BEGIN = 0x10000; + int THREAD_MODE_BACKGROUND_END = 0x20000; + + /** + * Thread priority error code + */ + int THREAD_PRIORITY_ERROR_RETURN = 0x7FFFFFFF; + /** * Reads data from the specified file or input/output (I/O) device. Reads * occur at the position specified by the file pointer if supported by the @@ -4152,6 +4186,45 @@ Pointer VirtualAllocEx(HANDLE hProcess, Pointer lpAddress, SIZE_T dwSize, */ boolean GetExitCodeThread(HANDLE hThread, IntByReference exitCode); + /** + * Gets the priority class of the specified process. + * + * @param hProcess A handle to the process. + * @return If the function succeeds, the return value is the priority class of + * the specified process. + *

If the function fails, the return value is zero.

+ */ + DWORD GetPriorityClass(HANDLE hProcess); + + /** + * Sets the priority class for the specified process. + * + * @param hProcess A handle to the process. + * @param dwPriorityClass The priority class for the process. + * @return If the function succeeds, the return value is nonzero. + */ + boolean SetPriorityClass(HANDLE hProcess, DWORD dwPriorityClass); + + /** + * Gets the priority value of the specified thread. + * + * @param hProcess A handle to the process. + * @return If the function succeeds, the return value is the priority class of + * the specified thread. + *

If the function fails, the return value is + * THREAD_PRIORITY_ERROR_RETURN.

+ */ + int GetThreadPriority(HANDLE hProcess); + + /** + * Sets the priority value for the specified thread. + * + * @param hThread A handle to the thread whose priority value is to be set. + * @param nPriority The priority value for the thread. + * @return If the function succeeds, the return value is nonzero. + */ + boolean SetThreadPriority(HANDLE hThread, int nPriority); + /** * Releases, decommits, or releases and decommits a region of memory within * the virtual address space of a specified process. diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java index a77afc43d..26a15ff2d 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java @@ -1258,6 +1258,160 @@ public static String expandEnvironmentStrings(String input) { } } + /** + * Gets the priority class of the current process. + * + * @return The priority class of the current process. + * @throws Win32Exception if an error occurs. + */ + public static DWORD getCurrentProcessPriority() { + final DWORD dwPriorityClass = Kernel32.INSTANCE.GetPriorityClass(Kernel32.INSTANCE.GetCurrentProcess()); + if (dwPriorityClass.longValue() == 0L) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + return dwPriorityClass; + } + + /** + * Sets the priority class for the current process. + * + * @param dwPriorityClass The priority class for the process. + * @throws Win32Exception if an error occurs. + */ + public static void setCurrentProcessPriority(final DWORD dwPriorityClass) { + if (!Kernel32.INSTANCE.SetPriorityClass(Kernel32.INSTANCE.GetCurrentProcess(), dwPriorityClass)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } + + /** + * Gets the priority value of the current thread. + * + * @return The priority value of the current thread. + * @throws Win32Exception if an error occurs. + */ + public static int getCurrentThreadPriority() { + final int nPriority = Kernel32.INSTANCE.GetThreadPriority(Kernel32.INSTANCE.GetCurrentThread()); + if (nPriority == THREAD_PRIORITY_ERROR_RETURN) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + return nPriority; + } + + /** + * Sets the priority value for the current thread. + * + * @param nPriority The priority value for the thread. + * @throws Win32Exception if an error occurs. + */ + public static void setCurrentThreadPriority(final int nPriority) { + if (!Kernel32.INSTANCE.SetThreadPriority(Kernel32.INSTANCE.GetCurrentThread(), nPriority)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } + + /** + * Gets the priority class of the specified process. + * + * @param pid Identifier for the running process. + * @throws Win32Exception if an error occurs. + */ + public static DWORD getProcessPriority(final int pid) { + final HANDLE hProcess = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_QUERY_INFORMATION , false, pid); + if (hProcess == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + Win32Exception we = null; + try { + final DWORD dwPriorityClass = Kernel32.INSTANCE.GetPriorityClass(hProcess); + if (dwPriorityClass.longValue() == 0L) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + return dwPriorityClass; + } catch (final Win32Exception e) { + we = e; + } finally { + cleanUp(hProcess, we); + } + } + + /** + * Sets the priority class for the specified process. + * + * @param pid Identifier for the running process. + * @param dwPriorityClass The priority class for the process. + * @throws Win32Exception if an error occurs. + */ + public static void setProcessPriority(final int pid, final DWORD dwPriorityClass) { + final HANDLE hProcess = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_SET_INFORMATION, false, pid); + if (hProcess == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + Win32Exception we = null; + try { + if (!Kernel32.INSTANCE.SetPriorityClass(hProcess, dwPriorityClass)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } catch (final Win32Exception e) { + we = e; + } finally { + cleanUp(hProcess, we); + } + } + + /** + * Gets the priority value of the specified thread. + * + * @param tid Identifier for the running thread. + * @throws Win32Exception if an error occurs. + */ + public static int getThreadPriority(final int tid) { + final HANDLE hThread = Kernel32.INSTANCE.OpenThread(WinNT.THREAD_QUERY_INFORMATION, false, tid); + if (hThread == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + Win32Exception we = null; + try { + final int nPriority = Kernel32.INSTANCE.GetThreadPriority(hThread); + if (nPriority == Kernel32.THREAD_PRIORITY_ERROR_RETURN) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + return nPriority; + } catch (final Win32Exception e) { + we = e; + } finally { + cleanUp(hThread, we); + } + } + + /** + * Sets the priority value for the specified thread. + * + * @param tid Identifier for the running thread. + * @param nPriority The priority value for the thread. + * @throws Win32Exception if an error occurs. + */ + public static void setThreadPriority(final int tid, final int nPriority) { + final HANDLE hThread = Kernel32.INSTANCE.OpenThread(WinNT.THREAD_SET_INFORMATION, false, tid); + if (hThread == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + Win32Exception we = null; + try { + if (!Kernel32.INSTANCE.SetThreadPriority(hThread, nPriority)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } catch (final Win32Exception e) { + we = e; + } finally { + cleanUp(hThread, we); + } + } + private static void cleanUp(final HANDLE h, Win32Exception we) { try { closeHandle(h); diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java index d964c70de..a3086be9c 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java @@ -2099,4 +2099,24 @@ public void testVirtualLockUnlock() { // Unlocking an unlocked region should fail assertFalse(Kernel32.INSTANCE.VirtualUnlock(mem, new SIZE_T(4096))); } + + public void testGetPriorityClass() { + final HANDLE selfHandle = Kernel32.INSTANCE.GetCurrentProcess(); + assertFalse(Kernel32.INSTANCE.GetPriorityClass(selfHandle).longValue() == 0L); + } + + public void testSetPriorityClass() { + final HANDLE selfHandle = Kernel32.INSTANCE.GetCurrentProcess(); + assertTrue(Kernel32.INSTANCE.SetPriorityClass(selfHandle, Kernel32.HIGH_PRIORITY_CLASS)); + } + + public void testGetThreadPriority() { + final HANDLE selfHandle = Kernel32.INSTANCE.GetCurrentProcess(); + assertFalse(Kernel32.INSTANCE.GetThreadPriority(selfHandle) == Kernel32.THREAD_PRIORITY_ERROR_RETURN); + } + + public void testSetThreadPriority() { + final HANDLE selfHandle = Kernel32.INSTANCE.GetCurrentThread(); + assertTrue(Kernel32.INSTANCE.SetThreadPriority(selfHandle, Kernel32.THREAD_PRIORITY_ABOVE_NORMAL)); + } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java index cdb5c373f..f86c701f1 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java @@ -513,4 +513,40 @@ public void testGetLogicalProcessorInformationEx() { assertTrue(cache.associativity == WinNT.CACHE_FULLY_ASSOCIATIVE || cache.associativity > 0); } } + + public void testGetCurrentProcessPriority() { + Kernel32Util.getCurrentProcessPriority(); + } + + public void testSetCurrentProcessPriority() { + Kernel32Util.setCurrentProcessPriority(Kernel32.HIGH_PRIORITY_CLASS); + } + + public void testGetCurrentThreadPriority() { + Kernel32Util.getCurrentThreadPriority(); + } + + public void testSetCurrentThreadPriority() { + Kernel32Util.setCurrentThreadPriority(Kernel32.THREAD_PRIORITY_ABOVE_NORMAL); + } + + public void testGetProcessPriority() { + final int pid = Kernel32.INSTANCE.GetCurrentProcessId(); + Kernel32Util.getProcessPriority(pid); + } + + public void testSetProcessPriority() { + final int pid = Kernel32.INSTANCE.GetCurrentProcessId(); + Kernel32Util.setProcessPriority(pid, Kernel32.HIGH_PRIORITY_CLASS); + } + + public void testGetThreadPriority() { + final int tid = Kernel32.INSTANCE.GetCurrentThreadId(); + Kernel32Util.getThreadPriority(tid); + } + + public void testSetThreadPriority() { + final int tid = Kernel32.INSTANCE.GetCurrentThreadId(); + Kernel32Util.setThreadPriority(tid, Kernel32.THREAD_PRIORITY_ABOVE_NORMAL); + } }