Index: trunk/src/VBox/Runtime/Makefile.kmk
===================================================================
--- trunk/src/VBox/Runtime/Makefile.kmk	(revision 77907)
+++ trunk/src/VBox/Runtime/Makefile.kmk	(revision 77910)
@@ -1691,4 +1691,7 @@
 	common/misc/RTFileOpenV.cpp \
 	common/misc/RTMemWipeThoroughly.cpp \
+	common/misc/req.cpp \
+	common/misc/reqqueue.cpp \
+	common/misc/reqpool.cpp \
 	common/misc/sanity-c.c \
 	common/misc/sanity-cpp.cpp \
Index: trunk/src/VBox/Runtime/common/misc/reqqueue.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/misc/reqqueue.cpp	(revision 77907)
+++ trunk/src/VBox/Runtime/common/misc/reqqueue.cpp	(revision 77910)
@@ -167,5 +167,4 @@
             /* Process the request. */
             rc = rtReqProcessOne(pReq);
-            AssertRC(rc);
             if (rc != VINF_SUCCESS)
             {
Index: trunk/src/VBox/Runtime/include/internal/thread.h
===================================================================
--- trunk/src/VBox/Runtime/include/internal/thread.h	(revision 77907)
+++ trunk/src/VBox/Runtime/include/internal/thread.h	(revision 77910)
@@ -262,4 +262,15 @@
 #endif
 
+/* thread-posix.cpp */
+#ifdef IN_RING3
+# if !defined(RT_OS_WINDOWS) && !defined(RT_OS_OS2) && !defined(RT_OS_DARWIN)
+#  define RTTHREAD_POSIX_WITH_CREATE_PRIORITY_PROXY
+# endif
+# ifdef RTTHREAD_POSIX_WITH_CREATE_PRIORITY_PROXY
+DECLHIDDEN(bool) rtThreadPosixPriorityProxyStart(void);
+DECLHIDDEN(int)  rtThreadPosixPriorityProxyCall(PRTTHREADINT pTargetThread, PFNRT pfnFunction, int cArgs, ...);
+# endif
+#endif
+
 #ifdef IPRT_INCLUDED_asm_h
 
Index: trunk/src/VBox/Runtime/r3/darwin/sched-darwin.cpp
===================================================================
--- trunk/src/VBox/Runtime/r3/darwin/sched-darwin.cpp	(revision 77907)
+++ trunk/src/VBox/Runtime/r3/darwin/sched-darwin.cpp	(revision 77910)
@@ -99,4 +99,21 @@
 {
     {
+        RTPROCPRIORITY_DEFAULT, "Default",
+        {
+            { RTTHREADTYPE_INVALID,                 INT_MIN, INT_MIN },
+            { RTTHREADTYPE_INFREQUENT_POLLER,       29, 29 },
+            { RTTHREADTYPE_MAIN_HEAVY_WORKER,       30, 30 },
+            { RTTHREADTYPE_EMULATION,               31, 31 }, /* the default priority */
+            { RTTHREADTYPE_DEFAULT,                 32, 32 },
+            { RTTHREADTYPE_GUI,                     32, 32 },
+            { RTTHREADTYPE_MAIN_WORKER,             32, 32 },
+            { RTTHREADTYPE_VRDP_IO,                 39, 39 },
+            { RTTHREADTYPE_DEBUGGER,                42, 42 },
+            { RTTHREADTYPE_MSG_PUMP,                47, 47 },
+            { RTTHREADTYPE_IO,                      52, 52 },
+            { RTTHREADTYPE_TIMER,                   55, 55 }
+        }
+    },
+    {
         RTPROCPRIORITY_LOW, "Low",
         {
@@ -207,12 +224,13 @@
  *
  * @returns The base priority
- */
-static int rtSchedDarwinGetBasePriority(void)
+ * @param   pThread     The thread to get it for.  NULL for current.
+ */
+static int rtSchedDarwinGetBasePriority(PRTTHREADINT pThread)
 {
     /* the base_priority. */
-    mach_msg_type_number_t              Count = POLICY_TIMESHARE_INFO_COUNT;
-    struct policy_timeshare_info        TSInfo = {0,0,0,0,0};
-    kern_return_t                       krc;
-    krc = thread_info(mach_thread_self(), THREAD_SCHED_TIMESHARE_INFO, (thread_info_t)&TSInfo, &Count);
+    mach_msg_type_number_t       Count  = POLICY_TIMESHARE_INFO_COUNT;
+    struct policy_timeshare_info TSInfo = {0,0,0,0,0};
+    kern_return_t krc = thread_info(!pThread ? mach_thread_self() : pthread_mach_thread_np((pthread_t)pThread->Core.Key),
+                                    THREAD_SCHED_TIMESHARE_INFO, (thread_info_t)&TSInfo, &Count);
     Assert(krc == KERN_SUCCESS);
 
@@ -228,5 +246,5 @@
      * Get the current priority.
      */
-    int iBasePriority = rtSchedDarwinGetBasePriority();
+    int iBasePriority = rtSchedDarwinGetBasePriority(NULL);
     Assert(iBasePriority >= 0 && iBasePriority <= 63);
 
@@ -277,5 +295,4 @@
 DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
 {
-    Assert(pThread->Core.Key == pthread_self());
     Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
     AssertMsg(g_pProcessPriority && g_pProcessPriority->aTypes[enmType].enmType == enmType,
@@ -305,19 +322,26 @@
         {
             int i = 0;
-            int iBasePriority = rtSchedDarwinGetBasePriority();
-
-            while (!err && iBasePriority < iDesiredBasePriority && i++ < 256)
+            int iBasePriority = rtSchedDarwinGetBasePriority(pThread);
+
+            while (   !err
+                   && iBasePriority < iDesiredBasePriority
+                   && i++ < 256)
             {
                 SchedParam.sched_priority = ++iPriority;
                 err = pthread_setschedparam((pthread_t)pThread->Core.Key, iSchedPolicy, &SchedParam);
-                iBasePriority = rtSchedDarwinGetBasePriority();
+                iBasePriority = rtSchedDarwinGetBasePriority(pThread);
             }
 
-            while (!err && iBasePriority > iDesiredBasePriority && i++ < 256)
+            while (   !err
+                   && iPriority > 0
+                   && iBasePriority > iDesiredBasePriority
+                   && i++ < 256)
             {
                 SchedParam.sched_priority = --iPriority;
                 err = pthread_setschedparam((pthread_t)pThread->Core.Key, iSchedPolicy, &SchedParam);
-                iBasePriority = rtSchedDarwinGetBasePriority();
+                iBasePriority = rtSchedDarwinGetBasePriority(pThread);
             }
+
+            return VINF_SUCCESS;
         }
     }
Index: trunk/src/VBox/Runtime/r3/linux/sched-linux.cpp
===================================================================
--- trunk/src/VBox/Runtime/r3/linux/sched-linux.cpp	(revision 77907)
+++ trunk/src/VBox/Runtime/r3/linux/sched-linux.cpp	(revision 77910)
@@ -120,4 +120,17 @@
     int                 iPthreadPolicy;
 } SAVEDPRIORITY, *PSAVEDPRIORITY;
+
+
+/**
+ * Priorities for checking by separate thread
+ * @internal
+ */
+typedef struct
+{
+    /** The current thread priority to assume first. */
+    int                 iCurrent;
+    /** The thread priority to try set afterwards. */
+    int                 iNew;
+} VALIDATORPRIORITYPAIR, *PVALIDATORPRIORITYPAIR;
 
 
@@ -306,8 +319,22 @@
 
 /**
+ * Called on the priority proxy thread if requested running, otherwise
+ * rtSchedRunThread() calls it directly.
+ */
+static DECLCALLBACK(int) rtSchedRunThreadCallback(pthread_t *pThread, void *(*pfnThread)(void *pvArg), void *pvArg)
+{
+    int rc = pthread_create(pThread, NULL, pfnThread, pvArg);
+    if (!rc)
+        return VINF_SUCCESS;
+    return RTErrConvertFromErrno(rc);
+}
+
+
+/**
  * Starts a worker thread and wait for it to complete.
+ *
  * We cannot use RTThreadCreate since we're already owner of the RW lock.
  */
-static int rtSchedRunThread(void *(*pfnThread)(void *pvArg), void *pvArg)
+static int rtSchedRunThread(void *(*pfnThread)(void *pvArg), void *pvArg, bool fUsePriorityProxy)
 {
     /*
@@ -315,6 +342,15 @@
      */
     pthread_t Thread;
-    int rc = pthread_create(&Thread, NULL, pfnThread, pvArg);
-    if (!rc)
+    int rc;
+#ifndef RTTHREAD_POSIX_WITH_CREATE_PRIORITY_PROXY
+    RT_NOREF(fUsePriorityProxy);
+#else
+    if (   fUsePriorityProxy
+        && rtThreadPosixPriorityProxyStart())
+        rc = rtThreadPosixPriorityProxyCall(NULL, (PFNRT)rtSchedRunThreadCallback, 3, &Thread, pfnThread, pvArg);
+    else
+#endif
+        rc = rtSchedRunThreadCallback(&Thread, pfnThread, pvArg);
+    if (RT_SUCCESS(rc))
     {
         /*
@@ -330,5 +366,5 @@
         return (int)(uintptr_t)pvRet;
     }
-    return RTErrConvertFromErrno(rc);
+    return rc;
 }
 
@@ -435,5 +471,5 @@
         &&  iStart != g_iMinPriority)
     {
-        if (rtSchedRunThread(rtSchedNativeSubProberThread, (void *)(intptr_t)iStart) == 0)
+        if (rtSchedRunThread(rtSchedNativeSubProberThread, (void *)(intptr_t)iStart, false /*fUsePriorityProxy*/) == 0)
             g_fScrewedUpMaxPriorityLimitInheritance = false;
     }
@@ -465,5 +501,5 @@
         /** @todo */
 #endif
-        int rc = rtSchedRunThread(rtSchedNativeProberThread, NULL);
+        int rc = rtSchedRunThread(rtSchedNativeProberThread, NULL, false /*fUsePriorityProxy*/);
         if (RT_FAILURE(rc))
             return rc;
@@ -499,26 +535,62 @@
 static void *rtSchedNativeValidatorThread(void *pvUser)
 {
-    const PROCPRIORITY *pCfg = (const PROCPRIORITY *)pvUser;
+    PVALIDATORPRIORITYPAIR pPrioPair = (PVALIDATORPRIORITYPAIR)pvUser;
     SAVEDPRIORITY SavedPriority;
     rtSchedNativeSave(&SavedPriority);
 
-    /*
-     * Try out the priorities from the top and down.
-     */
     int rc = VINF_SUCCESS;
+
+    /*
+     * Set the priority to the current value for specified thread type
+     */
+    if (setpriority(PRIO_PROCESS, 0, pPrioPair->iCurrent))
+        rc = RTErrConvertFromErrno(errno);
+
+    /*
+     * Try set the new priority.
+     */
+    if (RT_SUCCESS(rc) && setpriority(PRIO_PROCESS, 0, pPrioPair->iNew))
+        rc = RTErrConvertFromErrno(errno);
+
+    /* done */
+    rtSchedNativeRestore(&SavedPriority);
+    return (void *)(intptr_t)rc;
+}
+
+
+/**
+ * Validates the ability to apply suggested priority scheme.
+ *
+ * The function checks that we're able to apply all the thread types in the
+ * suggested priority scheme.
+ *
+ * @returns iprt status code.
+ * @param   pCfg                The priority scheme to validate.
+ * @param   fHavePriorityProxy  Set if we've got a priority proxy thread,
+ *                              otherwise clear.
+ */
+static int rtSchedNativeCheckThreadTypes(const PROCPRIORITY *pCfg, bool fHavePriorityProxy)
+{
+    /** @todo Only check transitions of thread types that actually are in use.
+     * For the others, just check we can create threads with the new priority
+     * scheme (ignoring the old). Best done by having an array of
+     * per-threadtype counters in common/misc/thread.cpp. */
     int i = RTTHREADTYPE_END;
     while (--i > RTTHREADTYPE_INVALID)
     {
-        int iPriority = pCfg->paTypes[i].iPriority + pCfg->iDelta;
-        if (setpriority(PRIO_PROCESS, 0, iPriority))
-        {
-            rc = RTErrConvertFromErrno(errno);
-            break;
-        }
+        VALIDATORPRIORITYPAIR PrioPair;
+        PrioPair.iCurrent = g_pProcessPriority->paTypes[i].iPriority + g_pProcessPriority->iDelta;
+        PrioPair.iNew     = pCfg->paTypes[i].iPriority               + pCfg->iDelta;
+
+#ifdef RT_STRICT
+        int const iPriority = getpriority(PRIO_PROCESS, 0);
+#endif
+        int rc = rtSchedRunThread(rtSchedNativeValidatorThread, &PrioPair, fHavePriorityProxy /*fUsePriorityProxy*/);
+        Assert(getpriority(PRIO_PROCESS, 0) == iPriority);
+
+        if (RT_FAILURE(rc))
+            return rc;
     }
-
-    /* done */
-    rtSchedNativeRestore(&SavedPriority);
-    return (void *)(intptr_t)rc;
+    return VINF_SUCCESS;
 }
 
@@ -537,7 +609,25 @@
     Assert(enmPriority > RTPROCPRIORITY_INVALID && enmPriority < RTPROCPRIORITY_LAST);
 
-    int rc = VINF_SUCCESS;
+#ifdef RTTHREAD_POSIX_WITH_CREATE_PRIORITY_PROXY
+    /*
+     * Make sure the proxy creation thread is started so we don't 'lose' our
+     * initial priority if it's lowered.
+     */
+    bool const fHavePriorityProxy = rtThreadPosixPriorityProxyStart();
+#else
+    bool const fHavePriorityProxy = false;
+#endif
+
+    int rc;
     if (enmPriority == RTPROCPRIORITY_DEFAULT)
-        g_pProcessPriority = &g_aDefaultPriority;
+    {
+        /*
+         * If we've lowered priority since the process started, it may be impossible
+         * to raise it again for existing thread (new threads will work fine).
+         */
+        rc = SchedNativeCheckThreadTypes(&g_aDefaultPriority);
+        if (RT_SUCCESS(rc))
+            g_pProcessPriority = &g_aDefaultPriority;
+    }
     else
     {
@@ -545,13 +635,10 @@
          * Find a configuration which matches and can be applied.
          */
-        rc = VERR_FILE_NOT_FOUND;
+        rc = VERR_NOT_FOUND;
         for (unsigned i = 0; i < RT_ELEMENTS(g_aUnixConfigs); i++)
-        {
             if (g_aUnixConfigs[i].enmPriority == enmPriority)
             {
-                int iPriority = getpriority(PRIO_PROCESS, 0);
-                int rc3 = rtSchedRunThread(rtSchedNativeValidatorThread, (void *)&g_aUnixConfigs[i]);
-                Assert(getpriority(PRIO_PROCESS, 0) == iPriority); NOREF(iPriority);
-                if (RT_SUCCESS(rc3))
+                int rc2 = rtSchedNativeCheckThreadTypes(&g_aUnixConfigs[i], fHavePriorityProxy);
+                if (RT_SUCCESS(rc2))
                 {
                     g_pProcessPriority = &g_aUnixConfigs[i];
@@ -559,8 +646,7 @@
                     break;
                 }
-                if (rc == VERR_FILE_NOT_FOUND)
-                    rc = rc3;
+                if (rc == VERR_NOT_FOUND || rc == VERR_ACCESS_DENIED)
+                    rc = rc2;
             }
-        }
     }
 
@@ -574,4 +660,25 @@
 
 /**
+ * Called on the priority proxy thread if it's running, otherwise
+ * rtThreadNativeSetPriority calls it directly.
+ */
+static DECLCALLBACK(int) rtThreadLinuxSetPriorityCallback(PRTTHREADINT pThread, int iPriority)
+{
+    if (!setpriority(PRIO_PROCESS, pThread->tid, iPriority))
+    {
+        AssertMsg(iPriority == getpriority(PRIO_PROCESS, pThread->tid),
+                  ("iPriority=%d getpriority()=%d\n", iPriority, getpriority(PRIO_PROCESS, pThread->tid)));
+#ifdef THREAD_LOGGING
+        Log(("rtThreadNativeSetPriority: Thread=%p enmType=%d iPriority=%d pid=%d tid=%d\n",
+             pThread->Core.Key, enmType, iPriority, getpid(), pThread->tid));
+#endif
+        return VINF_SUCCESS;
+    }
+    AssertMsgFailed(("setpriority(,, %d) -> errno=%d rc=%Rrc\n", iPriority, errno, RTErrConvertFromErrno(errno)));
+    return VINF_SUCCESS; //non-fatal for now.
+}
+
+
+/**
  * Sets the priority of the thread according to the thread type
  * and current process priority.
@@ -589,26 +696,21 @@
     Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
     Assert(enmType == g_pProcessPriority->paTypes[enmType].enmType);
-    Assert((pthread_t)pThread->Core.Key == pthread_self()); RT_NOREF_PV(pThread);
-
-    /*
-     * Calculate the thread priority and apply it.
-     */
-    int rc = VINF_SUCCESS;
-    int iPriority = g_pProcessPriority->paTypes[enmType].iPriority + g_pProcessPriority->iDelta;
-    if (!setpriority(PRIO_PROCESS, 0, iPriority))
-    {
-        AssertMsg(iPriority == getpriority(PRIO_PROCESS, 0), ("iPriority=%d getpriority()=%d\n", iPriority, getpriority(PRIO_PROCESS, 0)));
-#ifdef THREAD_LOGGING
-        Log(("rtThreadNativeSetPriority: Thread=%p enmType=%d iPriority=%d pid=%d\n", pThread->Core.Key, enmType, iPriority, getpid()));
-#endif
-    }
-    else
-    {
-        rc = RTErrConvertFromErrno(errno);
-        AssertMsgFailed(("setpriority(,, %d) -> errno=%d rc=%Rrc\n", iPriority, errno, rc));
-        rc = VINF_SUCCESS; //non-fatal for now.
-    }
-
-    return rc;
-}
-
+
+    /*
+     * The thread ID is zero for alien threads, so skip these or we'd risk
+     * modifying our own priority.
+     */
+    if (!pThread->tid)
+        return VINF_SUCCESS;
+
+    /*
+     * Calculate the thread priority and apply it, preferrably via the priority proxy thread.
+     */
+    int const iPriority = g_pProcessPriority->paTypes[enmType].iPriority + g_pProcessPriority->iDelta;
+#ifdef RTTHREAD_POSIX_WITH_CREATE_PRIORITY_PROXY
+    if (rtThreadPosixPriorityProxyStart())
+        return rtThreadPosixPriorityProxyCall(pThread, (PFNRT)rtThreadLinuxSetPriorityCallback, 2, pThread, iPriority);
+#endif
+    return rtThreadLinuxSetPriorityCallback(pThread, iPriority);
+}
+
Index: trunk/src/VBox/Runtime/r3/posix/sched-posix.cpp
===================================================================
--- trunk/src/VBox/Runtime/r3/posix/sched-posix.cpp	(revision 77907)
+++ trunk/src/VBox/Runtime/r3/posix/sched-posix.cpp	(revision 77910)
@@ -323,5 +323,5 @@
 /** Set if we figure we have nice capability, meaning we can use setpriority
  * to raise the priority. */
-bool g_fCanNice = false;
+static bool g_fCanNice = false;
 
 
@@ -500,4 +500,5 @@
     /* done */
     rtSchedNativeRestore(&SavedPriority);
+    RT_NOREF(pvUser);
     return (void *)VINF_SUCCESS;
 }
@@ -634,5 +635,5 @@
     /* done */
     rtSchedNativeRestore(&SavedPriority);
-    return (void *)rc;
+    return (void *)(intptr_t)rc;
 }
 
@@ -650,4 +651,15 @@
     Assert(enmPriority > RTPROCPRIORITY_INVALID && enmPriority < RTPROCPRIORITY_LAST);
 
+#ifdef RTTHREAD_POSIX_WITH_CREATE_PRIORITY_PROXY
+    /*
+     * Make sure the proxy creation thread is started so we don't 'lose' our
+     * initial priority if it's lowered.
+     */
+    rtThreadPosixPriorityProxyStart();
+#endif
+
+    /*
+     * Nothing to validate for the default priority (assuming no external renice).
+     */
     int rc = VINF_SUCCESS;
     if (enmPriority == RTPROCPRIORITY_DEFAULT)
@@ -732,4 +744,38 @@
 
 /**
+ * Worker for rtThreadNativeSetPriority/OSPRIOSUP_PROCESS_AND_THREAD_LEVEL
+ * that's either called on the priority proxy thread or directly if no proxy.
+ */
+static DECLCALLBACK(int) rtThreadPosixSetPriorityOnProcAndThrdCallback(PRTTHREADINT pThread, RTTHREADTYPE enmType)
+{
+    struct sched_param  SchedParam = {-9999999};
+    int                 iPolicy = -7777777;
+    int rc = pthread_getschedparam((pthread_t)pThread->Core.Key, &iPolicy, &SchedParam);
+    if (!rc)
+    {
+        SchedParam.sched_priority = g_pProcessPriority->paTypes[enmType].iPriority
+            + g_pProcessPriority->iDelta
+            + sched_get_priority_min(iPolicy);
+
+        rc = pthread_setschedparam((pthread_t)pThread->Core.Key, iPolicy, &SchedParam);
+        if (!rc)
+        {
+#ifdef THREAD_LOGGING
+            Log(("rtThreadNativeSetPriority: Thread=%p enmType=%d iPolicy=%d sched_priority=%d pid=%d\n",
+                 pThread->Core.Key, enmType, iPolicy, SchedParam.sched_priority, getpid()));
+#endif
+            return VINF_SUCCESS;
+        }
+    }
+
+    int rcNative = rc;
+    rc = RTErrConvertFromErrno(rc);
+    AssertMsgFailed(("pthread_[gs]etschedparam(%p, %d, {%d}) -> rcNative=%d rc=%Rrc\n",
+                     (void *)pThread->Core.Key, iPolicy, SchedParam.sched_priority, rcNative, rc)); NOREF(rcNative);
+    return rc;
+}
+
+
+/**
  * Sets the priority of the thread according to the thread type
  * and current process priority.
@@ -746,5 +792,4 @@
     Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
     Assert(enmType == g_pProcessPriority->paTypes[enmType].enmType);
-    Assert((pthread_t)pThread->Core.Key == pthread_self());
 
     int rc = VINF_SUCCESS;
@@ -753,28 +798,11 @@
         case OSPRIOSUP_PROCESS_AND_THREAD_LEVEL:
         {
-            struct sched_param  SchedParam = {-9999999};
-            int                 iPolicy = -7777777;
-            pthread_t           Self = pthread_self();
-            rc = pthread_getschedparam(Self, &iPolicy, &SchedParam);
-            if (!rc)
-            {
-                SchedParam.sched_priority = g_pProcessPriority->paTypes[enmType].iPriority
-                    + g_pProcessPriority->iDelta
-                    + sched_get_priority_min(iPolicy);
-                rc = pthread_setschedparam(Self, iPolicy, &SchedParam);
-                if (!rc)
-                {
-#ifdef THREAD_LOGGING
-                    Log(("rtThreadNativeSetPriority: Thread=%p enmType=%d iPolicy=%d sched_priority=%d pid=%d\n",
-                         pThread->Core.Key, enmType, iPolicy, SchedParam.sched_priority, getpid()));
+#ifdef RTTHREAD_POSIX_WITH_CREATE_PRIORITY_PROXY
+            if (rtThreadPosixPriorityProxyStart())
+                rc = rtThreadPosixPriorityProxyCall(pThread, (PFNRT)rtThreadPosixSetPriorityOnProcAndThrdCallback,
+                                                    2, pThread, enmType);
+            else
 #endif
-                    break;
-                }
-            }
-
-            int rcNative = rc;
-            rc = RTErrConvertFromErrno(rc);
-            AssertMsgFailed(("pthread_[gs]etschedparam(%p, %d, {%d}) -> rcNative=%d rc=%Rrc\n",
-                             (void *)Self, iPolicy, SchedParam.sched_priority, rcNative, rc)); NOREF(rcNative);
+                rc = rtThreadPosixSetPriorityOnProcAndThrdCallback(pThread, enmType);
             break;
         }
@@ -782,4 +810,8 @@
         case OSPRIOSUP_THREAD_LEVEL:
         {
+            /* No cross platform way of getting the 'who' parameter value for
+               arbitrary threads, so this is restricted to the calling thread only. */
+            AssertReturn((pthread_t)pThread->Core.Key == pthread_self(), VERR_NOT_SUPPORTED);
+
             int iPriority = g_pProcessPriority->paTypes[enmType].iPriority + g_pProcessPriority->iDelta;
             if (!setpriority(PRIO_PROCESS, 0, iPriority))
Index: trunk/src/VBox/Runtime/r3/posix/thread-posix.cpp
===================================================================
--- trunk/src/VBox/Runtime/r3/posix/thread-posix.cpp	(revision 77907)
+++ trunk/src/VBox/Runtime/r3/posix/thread-posix.cpp	(revision 77910)
@@ -33,4 +33,5 @@
 #include <pthread.h>
 #include <signal.h>
+#include <stdlib.h>
 #if defined(RT_OS_LINUX)
 # include <unistd.h>
@@ -65,4 +66,9 @@
 #include <iprt/initterm.h>
 #include <iprt/string.h>
+#include <iprt/semaphore.h>
+#include <iprt/list.h>
+#include <iprt/once.h>
+#include <iprt/critsect.h>
+#include <iprt/req.h>
 #include "internal/thread.h"
 
@@ -111,4 +117,33 @@
 static PFNPTHREADSETNAME g_pfnThreadSetName = NULL;
 #endif /* IPRT_MAY_HAVE_PTHREAD_SET_NAME_NP */
+
+#ifdef RTTHREAD_POSIX_WITH_CREATE_PRIORITY_PROXY
+/** Atomic indicator of whether the priority proxy thread has been (attempted) started.
+ *
+ * The priority proxy thread is started under these circumstances:
+ *      - RTThreadCreate
+ *      - RTThreadSetType
+ *      - RTProcSetPriority
+ *
+ * Which means that we'll be single threaded when this is modified.
+ *
+ * Speical values:
+ *      - VERR_TRY_AGAIN:           Not yet started.
+ *      - VERR_WRONG_ORDER:         Starting.
+ *      - VINF_SUCCESS:             Started successfully.
+ *      - VERR_PROCESS_NOT_FOUND:   Stopping or stopped
+ *      - Other error status if failed to start.
+ *
+ * @note We could potentially optimize this by only start it when we lower the
+ *       priority of ourselves, the process, or a newly created thread.  But
+ *       that would means we would need to take multi-threading into account, so
+ *       let's not do that for now.
+ */
+static int32_t volatile g_rcPriorityProxyThreadStart            = VERR_TRY_AGAIN;
+/** The IPRT thread handle for the priority proxy. */
+static RTTHREAD         g_hRTThreadPosixPriorityProxyThread     = NIL_RTTHREAD;
+/** The priority proxy queue. */
+static RTREQQUEUE       g_hRTThreadPosixPriorityProxyQueue      = NIL_RTREQQUEUE;
+#endif /* RTTHREAD_POSIX_WITH_CREATE_PRIORITY_PROXY */
 
 
@@ -332,6 +367,163 @@
 }
 
-
-DECLHIDDEN(int) rtThreadNativeCreate(PRTTHREADINT pThread, PRTNATIVETHREAD pNativeThread)
+#ifdef RTTHREAD_POSIX_WITH_CREATE_PRIORITY_PROXY
+
+/**
+ * @callback_method_impl{FNRTTHREAD,
+ *  Priority proxy thread that services g_hRTThreadPosixPriorityProxyQueue.}
+ */
+static DECLCALLBACK(int) rtThreadPosixPriorityProxyThread(PRTTHREADINT, void *)
+{
+    for (;;)
+    {
+        RTREQQUEUE hReqQueue = g_hRTThreadPosixPriorityProxyQueue;
+        if (hReqQueue != NIL_RTREQQUEUE)
+            RTReqQueueProcess(hReqQueue, RT_INDEFINITE_WAIT);
+        else
+            break;
+
+        int32_t rc = ASMAtomicUoReadS32(&g_rcPriorityProxyThreadStart);
+        if (rc != VINF_SUCCESS && rc != VERR_WRONG_ORDER)
+            break;
+    }
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Just returns a non-success status codes to force the thread to re-evaluate
+ * the global shutdown variable.
+ */
+static DECLCALLBACK(int) rtThreadPosixPriorityProxyStopper(void)
+{
+    return VERR_CANCELLED;
+}
+
+
+/**
+ * An atexit() callback that stops the proxy creation/priority thread.
+ */
+static void rtThreadStopProxyThread(void)
+{
+    /*
+     * Signal to the thread that it's time to shut down.
+     */
+    int32_t rc = ASMAtomicXchgS32(&g_rcPriorityProxyThreadStart, VERR_PROCESS_NOT_FOUND);
+    if (RT_SUCCESS(rc))
+    {
+        /*
+         * Grab the associated handles.
+         */
+        RTTHREAD   hThread = g_hRTThreadPosixPriorityProxyThread;
+        RTREQQUEUE hQueue  = g_hRTThreadPosixPriorityProxyQueue;
+        g_hRTThreadPosixPriorityProxyQueue  = NIL_RTREQQUEUE;
+        g_hRTThreadPosixPriorityProxyThread = NIL_RTTHREAD;
+        ASMCompilerBarrier(); /* paranoia */
+
+        AssertReturnVoid(hThread != NIL_RTTHREAD);
+        AssertReturnVoid(hQueue != NIL_RTREQQUEUE);
+
+        /*
+         * Kick the thread so it gets out of any pending RTReqQueueProcess call ASAP.
+         */
+        rc = RTReqQueueCallEx(hQueue, NULL, 0 /*cMillies*/, RTREQFLAGS_IPRT_STATUS | RTREQFLAGS_NO_WAIT,
+                              (PFNRT)rtThreadPosixPriorityProxyStopper, 0);
+
+        /*
+         * Wait for the thread to complete.
+         */
+        rc = RTThreadWait(hThread, RT_SUCCESS(rc) ? RT_MS_1SEC * 5 : 32, NULL);
+        if (RT_SUCCESS(rc))
+            RTReqQueueDestroy(hQueue);
+        /* else: just leak the stuff, we're exitting, so nobody cares... */
+    }
+}
+
+
+/**
+ * Ensure that the proxy priority proxy thread has been started.
+ *
+ * Since we will always start a proxy thread when asked to create a thread,
+ * there is no need for serialization here.
+ *
+ * @retval  true if started
+ * @retval  false if it failed to start (caller must handle this scenario).
+ */
+DECLHIDDEN(bool) rtThreadPosixPriorityProxyStart(void)
+{
+    /*
+     * Read the result.
+     */
+    int rc = ASMAtomicUoReadS32(&g_rcPriorityProxyThreadStart);
+    if (rc != VERR_TRY_AGAIN)
+        return RT_SUCCESS(rc);
+
+    /* If this triggers then there is a very unexpected race somewhere.  It
+       should be harmless though. */
+    AssertReturn(ASMAtomicCmpXchgS32(&g_rcPriorityProxyThreadStart, VERR_WRONG_ORDER, VERR_TRY_AGAIN), false);
+
+    /*
+     * Not yet started, so do that.
+     */
+    rc = RTReqQueueCreate(&g_hRTThreadPosixPriorityProxyQueue);
+    if (RT_SUCCESS(rc))
+    {
+        rc = RTThreadCreate(&g_hRTThreadPosixPriorityProxyThread, rtThreadPosixPriorityProxyThread, NULL, 0 /*cbStack*/,
+                            RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "RTThrdPP");
+        if (RT_SUCCESS(rc))
+        {
+            ASMAtomicWriteS32(&g_rcPriorityProxyThreadStart, VINF_SUCCESS);
+
+            atexit(rtThreadStopProxyThread);
+            return true;
+        }
+        RTReqQueueCreate(&g_hRTThreadPosixPriorityProxyQueue);
+    }
+    ASMAtomicWriteS32(&g_rcPriorityProxyThreadStart, rc != VERR_WRONG_ORDER ? rc : VERR_PROCESS_NOT_FOUND);
+    return false;
+}
+
+
+/**
+ * Calls @a pfnFunction from the priority proxy thread.
+ *
+ * Caller must have called rtThreadPosixStartProxy() to check that the priority
+ * proxy thread is running.
+ *
+ * @returns
+ * @param   pTargetThread   The target thread, NULL if not applicable.  This is
+ *                          so we can skip calls pertaining to the priority
+ *                          proxy thread itself.
+ * @param   pfnFunction     The function to call.  Must return IPRT status code.
+ * @param   cArgs           Number of arguments (see also RTReqQueueCall).
+ * @param   ...             Arguments (see also RTReqQueueCall).
+ */
+DECLHIDDEN(int) rtThreadPosixPriorityProxyCall(PRTTHREADINT pTargetThread, PFNRT pfnFunction, int cArgs, ...)
+{
+    int rc;
+    if (   !pTargetThread
+        || pTargetThread->pfnThread != rtThreadPosixPriorityProxyThread)
+    {
+        va_list va;
+        va_start(va, cArgs);
+        PRTREQ pReq;
+        rc = RTReqQueueCallV(g_hRTThreadPosixPriorityProxyQueue, &pReq, RT_INDEFINITE_WAIT, RTREQFLAGS_IPRT_STATUS,
+                             pfnFunction, cArgs, va);
+        va_end(va);
+        RTReqRelease(pReq);
+    }
+    else
+        rc = VINF_SUCCESS;
+    return rc;
+}
+
+#endif /* !RTTHREAD_POSIX_WITH_CREATE_PRIORITY_PROXY */
+
+/**
+ * Worker for rtThreadNativeCreate that's either called on the priority proxy
+ * thread or directly on the calling thread depending on the proxy state.
+ */
+static DECLCALLBACK(int) rtThreadNativeInternalCreate(PRTTHREADINT pThread, PRTNATIVETHREAD pNativeThread)
 {
     /*
@@ -377,4 +569,29 @@
 
 
+DECLHIDDEN(int) rtThreadNativeCreate(PRTTHREADINT pThread, PRTNATIVETHREAD pNativeThread)
+{
+#ifdef RTTHREAD_POSIX_WITH_CREATE_PRIORITY_PROXY
+    /*
+     * If we have a priority proxy thread, use it.  Make sure to ignore the
+     * staring of the proxy thread itself.
+     */
+    if (   pThread->pfnThread != rtThreadPosixPriorityProxyThread
+        && rtThreadPosixPriorityProxyStart())
+    {
+        PRTREQ pReq;
+        int rc = RTReqQueueCall(g_hRTThreadPosixPriorityProxyQueue, &pReq, RT_INDEFINITE_WAIT,
+                                (PFNRT)rtThreadNativeInternalCreate, 2, pThread, pNativeThread);
+        RTReqRelease(pReq);
+        return rc;
+    }
+
+    /*
+     * Fall back on creating it directly without regard to priority proxying.
+     */
+#endif
+    return rtThreadNativeInternalCreate(pThread, pNativeThread);
+}
+
+
 RTDECL(RTTHREAD) RTThreadSelf(void)
 {
Index: trunk/src/VBox/Runtime/r3/win/sched-win.cpp
===================================================================
--- trunk/src/VBox/Runtime/r3/win/sched-win.cpp	(revision 77907)
+++ trunk/src/VBox/Runtime/r3/win/sched-win.cpp	(revision 77910)
@@ -328,5 +328,7 @@
 
 #ifdef WIN32_SCHED_ENABLED
-    if (SetThreadPriority(rtThreadNativeGetHandle(pThread), g_pProcessPriority->aTypes[enmType].iThreadPriority))
+    HANDLE hThread = rtThreadNativeGetHandle(pThread);
+    if (   hThread == NULL /* No handle for alien threads. */
+        || SetThreadPriority(hThread, g_pProcessPriority->aTypes[enmType].iThreadPriority))
         return VINF_SUCCESS;
 
