Index: /trunk/src/libs/xpcom18a4/ipc/ipcd/client/public/ipcdclient.h
===================================================================
--- /trunk/src/libs/xpcom18a4/ipc/ipcd/client/public/ipcdclient.h	(revision 30051)
+++ /trunk/src/libs/xpcom18a4/ipc/ipcd/client/public/ipcdclient.h	(revision 30052)
@@ -68,4 +68,11 @@
   NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GENERAL, 10)
 
+#ifdef VBOX
+/* This error code can only be returned by the selector functions called by
+ * WaitTarget. The message should be dropped without processing. */
+#define IPC_DISCARD_MESSAGE \
+  NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GENERAL, 12)
+#endif /* VBOX */
+
 /* This error code is returned by IPC_WaitMessage under certain conditions. */
 #define IPC_ERROR_WOULD_BLOCK NS_BASE_STREAM_WOULD_BLOCK
@@ -99,5 +106,5 @@
  * the IPC_WaitMessage function, that will immediately fail with an error.
  * OnClientStateChange is called on the same thread where this function is
- * called.  
+ * called.
  *
  * @returns NS_ERROR_NOT_INITIALIZED if IPC_Init has not been called or if
Index: /trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp
===================================================================
--- /trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp	(revision 30051)
+++ /trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp	(revision 30052)
@@ -289,5 +289,5 @@
 // message target.  the selector is called while inside the target's monitor.
 
-typedef PRBool (* ipcMessageSelector)(
+typedef nsresult (* ipcMessageSelector)(
   void *arg,
   ipcTargetData *td,
@@ -296,8 +296,8 @@
 
 // selects any
-static PRBool
+static nsresult
 DefaultSelector(void *arg, ipcTargetData *td, const ipcMessage *msg)
 {
-  return PR_TRUE;
+  return NS_OK;
 }
 
@@ -379,8 +379,8 @@
       {
         lastChecked->SetFlag(IPC_MSG_FLAG_IN_PROCESS);
-        PRBool accepted = (aSelector)(aArg, td, lastChecked);
+        nsresult acceptedRV = (aSelector)(aArg, td, lastChecked);
         lastChecked->ClearFlag(IPC_MSG_FLAG_IN_PROCESS);
 
-        if (accepted)
+        if (acceptedRV != IPC_WAIT_NEXT_MESSAGE)
         {
           // remove from pending queue
@@ -389,8 +389,11 @@
           else
             td->pendingQ.RemoveFirst();
-          lastChecked->mNext = nsnull;
-
-          *aMsg = lastChecked;
-          break;
+
+          if (acceptedRV != IPC_DISCARD_MESSAGE)
+          {
+            lastChecked->mNext = nsnull;
+            *aMsg = lastChecked;
+            break;
+          }
         }
       }
@@ -411,6 +414,6 @@
        * This is necessary as there might be several threads waiting for
        * a message from a single client, and only one gets the DOWN msg. */
-      PRBool alive = (aSelector)(aArg, td, NULL);
-      if (!alive)
+      nsresult aliveRV = (aSelector)(aArg, td, NULL);
+      if (aliveRV != IPC_WAIT_NEXT_MESSAGE)
       {
         *aMsg = NULL;
@@ -598,13 +601,13 @@
 
 // selects the next IPCM message with matching request index
-static PRBool
+static nsresult
 WaitIPCMResponseSelector(void *arg, ipcTargetData *td, const ipcMessage *msg)
 {
 #ifdef VBOX
   if (!msg)
-    return PR_TRUE;
+    return IPC_WAIT_NEXT_MESSAGE;
 #endif /* VBOX */
   PRUint32 requestIndex = *(PRUint32 *) arg;
-  return IPCM_GetRequestIndex(msg) == requestIndex;
+  return IPCM_GetRequestIndex(msg) == requestIndex ? NS_OK : IPC_WAIT_NEXT_MESSAGE;
 }
 
@@ -929,5 +932,5 @@
 };
 
-static PRBool WaitMessageSelector(void *arg, ipcTargetData *td, const ipcMessage *msg)
+static nsresult WaitMessageSelector(void *arg, ipcTargetData *td, const ipcMessage *msg)
 {
   WaitMessageSelectorData *data = (WaitMessageSelectorData *) arg;
@@ -944,9 +947,7 @@
     nsresult rv = obs->OnMessageAvailable(IPC_SENDER_ANY, nsID(), 0, 0);
     if (rv != IPC_WAIT_NEXT_MESSAGE)
-    {
       data->senderDead = PR_TRUE;
-      return PR_FALSE;
-    }
-    return PR_TRUE;
+
+    return rv;
   }
 #endif /* VBOX */
@@ -975,5 +976,5 @@
 
             data->senderDead = PR_TRUE;
-            return PR_TRUE; // consume the message
+            return IPC_DISCARD_MESSAGE; // consume the message
           }
           else
@@ -990,8 +991,7 @@
             nsresult rv = obs->OnMessageAvailable(status->ClientID(), nsID(), 0, 0);
             if (rv != IPC_WAIT_NEXT_MESSAGE)
-            {
               data->senderDead = PR_TRUE;
-              return PR_TRUE; // consume the message
-            }
+
+            return IPC_DISCARD_MESSAGE; // consume the message
           }
         }
@@ -1019,8 +1019,8 @@
              * this case. A client ID wraparound can't falsely trigger
              * this, since the waiting thread would have hit the liveness
-             * check in the mean time. Also, DO NOT consume the message,
-             * otherwise it gets passed to the DConnect message handling
-             * without any further checks. IPCM messages are automatically
-             * discarded if they are left unclaimed. */
+             * check in the mean time. We MUST consume the message, otherwise
+             * IPCM messages pile up as long as there is a pending call, which
+             * can lead to severe processing overhead. */
+            return IPC_DISCARD_MESSAGE; // consume the message
           }
         }
@@ -1031,5 +1031,5 @@
         NS_NOTREACHED("unexpected message");
     }
-    return PR_FALSE; // continue iterating
+    return IPC_WAIT_NEXT_MESSAGE; // continue iterating
   }
 
@@ -1051,5 +1051,5 @@
 
   // stop iterating if we got a match that the observer accepted.
-  return rv != IPC_WAIT_NEXT_MESSAGE;
+  return rv != IPC_WAIT_NEXT_MESSAGE ? NS_OK : IPC_WAIT_NEXT_MESSAGE;
 }
 
