SetThreadPriority, Vista, and Autostart Locations

I ran across a post on the Vista Compatibility Team Blog entitled "SetThreadPriority from Run key" that discusses a change in Vista whereby calling SetThreadPriority from an application launched from the Startup folder and the "Run" key in the registry will not cause the thread's priority to be increased.

Wanting to verify and play around with this, I wrote a simple program that called SetThreadPriority to set the priority of the thread to THREAD_PRIORITY_HIGHEST. The program then immediately called GetThreadPriority to determine if the call to SetThreadPriority had any effect. Next, in a loop, the program then called SetThreadPriority / GetThreadPriority until either an error was encountered, or GetThreadPriority returned the expected priority. The program logged before and after each call to SetThreadPriority / GetThreadPriority the time, the action, and the either the parameters or the return value.

I set the program to be launched automatically by placing a shortcut in the "Startup" folder, and rebooted. Once the system came back up, I waited a bit and then examined the log. The first call to SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_HIGHEST ); returned TRUE. The first call to GetThreadPriority( GetCurrentThread() ); returned 0 indicating THREAD_PRIORITY_NORMAL. In other words, the call to SetThreadPriority had succeeded, but the priority of the thread remained unchanged. The calls to SetThreadPriority and GetThreadPriority in the loop were identical, and returned identical values. That is, until about 45 seconds into the program's execution, when the call to GetThreadPriority returned 2, indicating that the priority of the thread was THREAD_PRIORITY_HIGHEST. This matches what is mentioned in the "SetThreadPriority from Run key" blog entry, where it is stated that:

it is for about a minute or so after which the call to SetThreadPriority(THREAD_PRIORITY_HIGHEST ) will actually succeed in bumping up its priority level.

I repeated the same tests, using THREAD_PRIORITY_ABOVE_NORMAL in the call to SetThreadPriority, with the same results.

I also used THREAD_PRIORITY_BELOW_NORMAL in the call to SetThreadPriority as well as THREAD_PRIORITY_LOWEST; in these cases, the call indicated success and GetThreadPriority confirmed the change in priority immediately.

The next set of tests removed the call to SetThreadPriority in the loop - just the initial call to SetThreadPriority was made. The return indicated success, but the call to GetThreadPriority returned THREAD_PRIORITY_NORMAL for many minutes; as the loop was a tight loop, I terminated the process once it became apparent that there truly would be no change to the priority of the thread. This means that requests to increase the priority are not queued up or held for later processing. The call to increase priority indicates success, the priority is not changed, and unless the thread checks, it is none the wiser.

One other thing that I thought of trying was to see what happened when a thread in a process spawned by an "autostart" process called SetThreadPriority, as above. To do so, I modified the original program to accept a command-line parameter indicating that it should spawn another instance of itself. The thread in the spawned process behaved identically to the thread in the "autostart" process; this persisted 3 "levels" deep ("autostart" instance spawns instance x, which spawns instance y), which is as deep as I tried. The Vista Compatibility Team Blog entry only mentions the Startup folder and the "Run" key as being affected by this, but I wonder if other things may be affected. It is interesting (and a good thing!) that there is a mechanism in place to cause this behavior to affect processes spawned by autostart processes (otherwise, the "protection" offered by this feature is easily defeated).

As a last test, I invoked the test program manually as quickly as I could while Vista was still processing the login. The first attempt to change the priority of the thread succeeded, and the first call to GetThreadPriority confirmed the priority change. At the same time, Vista was processing the autostart instance of the program, which behaved as it had previously when started automatically. So there is not a blanket ban on priority boosting in the first minute or so - how a program is started truly affects what it can do.


No comments: