1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/* $Id$ */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/** @file
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * MS COM / XPCOM Abstraction Layer:
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Main event queue class declaration
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/*
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Copyright (C) 2006-2010 Oracle Corporation
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync *
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * available from http://www.virtualbox.org. This file is free software;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * you can redistribute it and/or modify it under the terms of the GNU
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * General Public License (GPL) as published by the Free Software
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#include "VBox/com/NativeEventQueue.h"
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#include <new> /* For bad_alloc. */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#ifdef RT_OS_DARWIN
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync# include <CoreFoundation/CFRunLoop.h>
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#endif
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#if defined(VBOX_WITH_XPCOM) && !defined(RT_OS_DARWIN) && !defined(RT_OS_OS2)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync# define USE_XPCOM_QUEUE
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#endif
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#include <iprt/err.h>
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#include <iprt/time.h>
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#include <iprt/thread.h>
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#include <iprt/log.h>
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#ifdef USE_XPCOM_QUEUE
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync# include <errno.h>
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#endif
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsyncnamespace com
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync{
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync// NativeEventQueue class
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync////////////////////////////////////////////////////////////////////////////////
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#ifndef VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync# define CHECK_THREAD_RET(ret) \
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync do { \
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync AssertMsg(GetCurrentThreadId() == mThreadId, ("Must be on event queue thread!")); \
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (GetCurrentThreadId() != mThreadId) \
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return ret; \
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync } while (0)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/** Magic LPARAM value for the WM_USER messages that we're posting.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @remarks This magic value is duplicated in
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * vboxapi/PlatformMSCOM::interruptWaitEvents(). */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#define EVENTQUEUE_WIN_LPARAM_MAGIC UINT32_C(0xf241b819)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#else // VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync# define CHECK_THREAD_RET(ret) \
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync do { \
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (!mEventQ) \
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return ret; \
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync BOOL isOnCurrentThread = FALSE; \
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync mEventQ->IsOnCurrentThread(&isOnCurrentThread); \
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync AssertMsg(isOnCurrentThread, ("Must be on event queue thread!")); \
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (!isOnCurrentThread) \
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return ret; \
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync } while (0)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#endif // VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/** Pointer to the main event queue. */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsyncNativeEventQueue *NativeEventQueue::sMainQueue = NULL;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#ifdef VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsyncstruct MyPLEvent : public PLEvent
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync{
6976ecae1d524fa439cc9aca14b612b262557cbevboxsync MyPLEvent(NativeEvent *e) : event(e) {}
6976ecae1d524fa439cc9aca14b612b262557cbevboxsync NativeEvent *event;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync};
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/* static */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsyncvoid *PR_CALLBACK com::NativeEventQueue::plEventHandler(PLEvent *self)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync{
6976ecae1d524fa439cc9aca14b612b262557cbevboxsync NativeEvent *ev = ((MyPLEvent *)self)->event;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (ev)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync ev->handler();
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync else
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync NativeEventQueue *eq = (NativeEventQueue *)self->owner;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync Assert(eq);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync eq->mInterrupted = true;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return NULL;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync}
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/* static */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsyncvoid PR_CALLBACK com::NativeEventQueue::plEventDestructor(PLEvent *self)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync{
6976ecae1d524fa439cc9aca14b612b262557cbevboxsync NativeEvent *ev = ((MyPLEvent *)self)->event;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (ev)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync delete ev;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync delete self;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync}
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#endif // VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/**
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Constructs an event queue for the current thread.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync *
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Currently, there can be only one event queue per thread, so if an event
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * queue for the current thread already exists, this object is simply attached
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * to the existing event queue.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsyncNativeEventQueue::NativeEventQueue()
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync{
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#ifndef VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync mThreadId = GetCurrentThreadId();
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync // force the system to create the message queue for the current thread
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync MSG msg;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (!DuplicateHandle(GetCurrentProcess(),
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync GetCurrentThread(),
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync GetCurrentProcess(),
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync &mhThread,
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync 0 /*dwDesiredAccess*/,
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync FALSE /*bInheritHandle*/,
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync DUPLICATE_SAME_ACCESS))
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync mhThread = INVALID_HANDLE_VALUE;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#else // VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync mEQCreated = false;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync mInterrupted = false;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync // Here we reference the global nsIEventQueueService instance and hold it
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync // until we're destroyed. This is necessary to keep NS_ShutdownXPCOM() away
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync // from calling StopAcceptingEvents() on all event queues upon destruction of
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync // nsIEventQueueService, and makes sense when, for some reason, this happens
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync // *before* we're able to send a NULL event to stop our event handler thread
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync // when doing unexpected cleanup caused indirectly by NS_ShutdownXPCOM()
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync // that is performing a global cleanup of everything. A good example of such
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync // situation is when NS_ShutdownXPCOM() is called while the VirtualBox component
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync // is still alive (because it is still referenced): eventually, it results in
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync // a VirtualBox::uninit() call from where it is already not possible to post
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync // NULL to the event thread (because it stopped accepting events).
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync nsresult rc = NS_GetEventQueueService(getter_AddRefs(mEventQService));
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (NS_SUCCEEDED(rc))
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = mEventQService->GetThreadEventQueue(NS_CURRENT_THREAD,
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync getter_AddRefs(mEventQ));
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (rc == NS_ERROR_NOT_AVAILABLE)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = mEventQService->CreateThreadEventQueue();
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (NS_SUCCEEDED(rc))
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync mEQCreated = true;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = mEventQService->GetThreadEventQueue(NS_CURRENT_THREAD,
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync getter_AddRefs(mEventQ));
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync AssertComRC(rc);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#endif // VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync}
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsyncNativeEventQueue::~NativeEventQueue()
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync{
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#ifndef VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (mhThread != INVALID_HANDLE_VALUE)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync CloseHandle(mhThread);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync mhThread = INVALID_HANDLE_VALUE;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#else // VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync // process all pending events before destruction
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (mEventQ)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (mEQCreated)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync mEventQ->StopAcceptingEvents();
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync mEventQ->ProcessPendingEvents();
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync mEventQService->DestroyThreadEventQueue();
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync mEventQ = nsnull;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync mEventQService = nsnull;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#endif // VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync}
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/**
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Initializes the main event queue instance.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @returns VBox status code.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync *
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @remarks If you're using the rest of the COM/XPCOM glue library,
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * com::Initialize() will take care of initializing and uninitializing
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * the NativeEventQueue class. If you don't call com::Initialize, you must
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * make sure to call this method on the same thread that did the
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * XPCOM initialization or we'll end up using the wrong main queue.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/* static */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsyncint NativeEventQueue::init()
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync{
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync Assert(sMainQueue == NULL);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync Assert(RTThreadIsMain(RTThreadSelf()));
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync try
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync sMainQueue = new NativeEventQueue();
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync AssertPtr(sMainQueue);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#ifdef VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync /* Check that it actually is the main event queue, i.e. that
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync we're called on the right thread. */
6976ecae1d524fa439cc9aca14b612b262557cbevboxsync nsCOMPtr<nsIEventQueue> q;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync nsresult rv = NS_GetMainEventQ(getter_AddRefs(q));
0d1bdd97805a814925cce1e8babc59027661e758vboxsync AssertComRCReturn(rv, VERR_INVALID_POINTER);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync Assert(q == sMainQueue->mEventQ);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync /* Check that it's a native queue. */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync PRBool fIsNative = PR_FALSE;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rv = sMainQueue->mEventQ->IsQueueNative(&fIsNative);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync Assert(NS_SUCCEEDED(rv) && fIsNative);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#endif // VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync catch (std::bad_alloc &ba)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync NOREF(ba);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return VERR_NO_MEMORY;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return VINF_SUCCESS;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync}
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/**
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Uninitialize the global resources (i.e. the main event queue instance).
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @returns VINF_SUCCESS
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/* static */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsyncint NativeEventQueue::uninit()
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync{
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (sMainQueue)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync /* Must process all events to make sure that no NULL event is left
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * after this point. It would need to modify the state of sMainQueue. */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#ifdef RT_OS_DARWIN /* Do not process the native runloop, the toolkit may not be ready for it. */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync sMainQueue->mEventQ->ProcessPendingEvents();
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#else
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync sMainQueue->processEventQueue(0);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#endif
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync delete sMainQueue;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync sMainQueue = NULL;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return VINF_SUCCESS;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync}
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/**
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Get main event queue instance.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync *
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Depends on init() being called first.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/* static */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsyncNativeEventQueue* NativeEventQueue::getMainEventQueue()
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync{
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return sMainQueue;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync}
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#ifdef VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync# ifdef RT_OS_DARWIN
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/**
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Wait for events and process them (Darwin).
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync *
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @retval VINF_SUCCESS
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @retval VERR_TIMEOUT
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @retval VERR_INTERRUPTED
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync *
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @param cMsTimeout How long to wait, or RT_INDEFINITE_WAIT.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsyncstatic int waitForEventsOnDarwin(RTMSINTERVAL cMsTimeout)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync{
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync /*
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Wait for the requested time, if we get a hit we do a poll to process
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * any other pending messages.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync *
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Note! About 1.0e10: According to the sources anything above 3.1556952e+9
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * means indefinite wait and 1.0e10 is what CFRunLoopRun() uses.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync CFTimeInterval rdTimeout = cMsTimeout == RT_INDEFINITE_WAIT ? 1e10 : (double)cMsTimeout / 1000;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync OSStatus orc = CFRunLoopRunInMode(kCFRunLoopDefaultMode, rdTimeout, true /*returnAfterSourceHandled*/);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (orc == kCFRunLoopRunHandledSource)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync OSStatus orc2 = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.0, false /*returnAfterSourceHandled*/);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if ( orc2 == kCFRunLoopRunStopped
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync || orc2 == kCFRunLoopRunFinished)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync orc = orc2;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if ( orc == 0 /*???*/
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync || orc == kCFRunLoopRunHandledSource)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return VINF_SUCCESS;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if ( orc == kCFRunLoopRunStopped
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync || orc == kCFRunLoopRunFinished)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return VERR_INTERRUPTED;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync AssertMsg(orc == kCFRunLoopRunTimedOut, ("Unexpected status code from CFRunLoopRunInMode: %#x", orc));
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return VERR_TIMEOUT;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync}
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync# else // !RT_OS_DARWIN
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/**
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Wait for events (generic XPCOM).
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync *
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @retval VINF_SUCCESS
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @retval VERR_TIMEOUT
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @retval VINF_INTERRUPTED
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @retval VERR_INTERNAL_ERROR_4
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync *
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @param pQueue The queue to wait on.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @param cMsTimeout How long to wait, or RT_INDEFINITE_WAIT.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsyncstatic int waitForEventsOnXPCOM(nsIEventQueue *pQueue, RTMSINTERVAL cMsTimeout)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync{
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync int fd = pQueue->GetEventQueueSelectFD();
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync fd_set fdsetR;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync FD_ZERO(&fdsetR);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync FD_SET(fd, &fdsetR);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync fd_set fdsetE = fdsetR;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync struct timeval tv = {0,0};
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync struct timeval *ptv;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (cMsTimeout == RT_INDEFINITE_WAIT)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync ptv = NULL;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync else
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync tv.tv_sec = cMsTimeout / 1000;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync tv.tv_usec = (cMsTimeout % 1000) * 1000;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync ptv = &tv;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync int rc = select(fd + 1, &fdsetR, NULL, &fdsetE, ptv);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (rc > 0)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = VINF_SUCCESS;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync else if (rc == 0)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = VERR_TIMEOUT;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync else if (errno == EINTR)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = VINF_INTERRUPTED;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync else
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync static uint32_t s_ErrorCount = 0;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (s_ErrorCount < 500)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync LogRel(("waitForEventsOnXPCOM rc=%d errno=%d\n", rc, errno));
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync ++s_ErrorCount;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync AssertMsgFailed(("rc=%d errno=%d\n", rc, errno));
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = VERR_INTERNAL_ERROR_4;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return rc;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync}
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync# endif // !RT_OS_DARWIN
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#endif // VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#ifndef VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/**
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Dispatch a message on Windows.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync *
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * This will pick out our events and handle them specially.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync *
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @returns @a rc or VERR_INTERRUPTED (WM_QUIT or NULL msg).
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @param pMsg The message to dispatch.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @param rc The current status code.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/*static*/
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsyncint NativeEventQueue::dispatchMessageOnWindows(MSG const *pMsg, int rc)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync{
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync /*
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Check for and dispatch our events.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if ( pMsg->hwnd == NULL
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync && pMsg->message == WM_USER)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (pMsg->lParam == EVENTQUEUE_WIN_LPARAM_MAGIC)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync NativeEvent *pEvent = (NativeEvent *)pMsg->wParam;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (pEvent)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync pEvent->handler();
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync delete pEvent;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync else
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = VERR_INTERRUPTED;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return rc;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync AssertMsgFailed(("lParam=%p wParam=%p\n", pMsg->lParam, pMsg->wParam));
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync /*
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Check for the quit message and dispatch the message the normal way.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (pMsg->message == WM_QUIT)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = VERR_INTERRUPTED;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync TranslateMessage(pMsg);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync DispatchMessage(pMsg);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return rc;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync}
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/**
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Process pending events (Windows).
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync *
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @retval VINF_SUCCESS
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @retval VERR_TIMEOUT
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @retval VERR_INTERRUPTED.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsyncstatic int processPendingEvents(void)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync{
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync int rc = VERR_TIMEOUT;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync MSG Msg;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (PeekMessage(&Msg, NULL /*hWnd*/, 0 /*wMsgFilterMin*/, 0 /*wMsgFilterMax*/, PM_REMOVE))
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = VINF_SUCCESS;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync do
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = NativeEventQueue::dispatchMessageOnWindows(&Msg, rc);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync while (PeekMessage(&Msg, NULL /*hWnd*/, 0 /*wMsgFilterMin*/, 0 /*wMsgFilterMax*/, PM_REMOVE));
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return rc;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync}
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#else // VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/**
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Process pending XPCOM events.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @param pQueue The queue to process events on.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @retval VINF_SUCCESS
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @retval VERR_TIMEOUT
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @retval VERR_INTERRUPTED (darwin only)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @retval VERR_INTERNAL_ERROR_2
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsyncstatic int processPendingEvents(nsIEventQueue *pQueue)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync{
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync /* ProcessPendingEvents doesn't report back what it did, so check here. */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync PRBool fHasEvents = PR_FALSE;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync nsresult hr = pQueue->PendingEvents(&fHasEvents);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (NS_FAILED(hr))
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return VERR_INTERNAL_ERROR_2;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync /* Process pending events. */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync int rc = VINF_SUCCESS;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (fHasEvents)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync pQueue->ProcessPendingEvents();
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync else
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = VERR_TIMEOUT;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync# ifdef RT_OS_DARWIN
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync /* Process pending native events. */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync int rc2 = waitForEventsOnDarwin(0);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (rc == VERR_TIMEOUT || rc2 == VERR_INTERRUPTED)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = rc2;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync# endif
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return rc;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync}
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#endif // VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/**
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Process events pending on this event queue, and wait up to given timeout, if
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * nothing is available.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync *
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Must be called on same thread this event queue was created on.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync *
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @param cMsTimeout The timeout specified as milliseconds. Use
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * RT_INDEFINITE_WAIT to wait till an event is posted on the
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * queue.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync *
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @returns VBox status code
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @retval VINF_SUCCESS if one or more messages was processed.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @retval VERR_TIMEOUT if cMsTimeout expired.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @retval VERR_INVALID_CONTEXT if called on the wrong thread.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @retval VERR_INTERRUPTED if interruptEventQueueProcessing was called.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * On Windows will also be returned when WM_QUIT is encountered.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * On Darwin this may also be returned when the native queue is
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * stopped or destroyed/finished.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @retval VINF_INTERRUPTED if the native system call was interrupted by a
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * an asynchronous event delivery (signal) or just felt like returning
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * out of bounds. On darwin it will also be returned if the queue is
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * stopped.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsyncint NativeEventQueue::processEventQueue(RTMSINTERVAL cMsTimeout)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync{
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync int rc;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync CHECK_THREAD_RET(VERR_INVALID_CONTEXT);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#ifdef VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync /*
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Process pending events, if none are available and we're not in a
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * poll call, wait for some to appear. (We have to be a little bit
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * careful after waiting for the events since Darwin will process
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * them as part of the wait, while the XPCOM case will not.)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync *
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Note! Unfortunately, WaitForEvent isn't interruptible with Ctrl-C,
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * while select() is. So we cannot use it for indefinite waits.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = processPendingEvents(mEventQ);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if ( rc == VERR_TIMEOUT
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync && cMsTimeout > 0)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync# ifdef RT_OS_DARWIN
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync /** @todo check how Ctrl-C works on Darwin. */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = waitForEventsOnDarwin(cMsTimeout);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (rc == VERR_TIMEOUT)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = processPendingEvents(mEventQ);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync# else // !RT_OS_DARWIN
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = waitForEventsOnXPCOM(mEventQ, cMsTimeout);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if ( RT_SUCCESS(rc)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync || rc == VERR_TIMEOUT)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = processPendingEvents(mEventQ);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync# endif // !RT_OS_DARWIN
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if ( ( RT_SUCCESS(rc)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync || rc == VERR_INTERRUPTED
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync || rc == VERR_TIMEOUT)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync && mInterrupted)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync mInterrupted = false;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = VERR_INTERRUPTED;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#else // !VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (cMsTimeout == RT_INDEFINITE_WAIT)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync BOOL fRet;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync MSG Msg;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = VINF_SUCCESS;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync while ( rc != VERR_INTERRUPTED
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync && (fRet = GetMessage(&Msg, NULL /*hWnd*/, WM_USER, WM_USER))
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync && fRet != -1)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = NativeEventQueue::dispatchMessageOnWindows(&Msg, rc);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (fRet == 0)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = VERR_INTERRUPTED;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync else if (fRet == -1)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = RTErrConvertFromWin32(GetLastError());
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync else
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = processPendingEvents();
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if ( rc == VERR_TIMEOUT
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync && cMsTimeout != 0)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync DWORD rcW = MsgWaitForMultipleObjects(1,
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync &mhThread,
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync TRUE /*fWaitAll*/,
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync cMsTimeout,
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync QS_ALLINPUT);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync AssertMsgReturn(rcW == WAIT_TIMEOUT || rcW == WAIT_OBJECT_0,
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync ("%d\n", rcW),
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync VERR_INTERNAL_ERROR_4);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync rc = processPendingEvents();
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#endif // !VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync Assert(rc != VERR_TIMEOUT || cMsTimeout != RT_INDEFINITE_WAIT);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return rc;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync}
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/**
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Interrupt thread waiting on event queue processing.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync *
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Can be called on any thread.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync *
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @returns VBox status code.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsyncint NativeEventQueue::interruptEventQueueProcessing()
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync{
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync /* Send a NULL event. This event will be picked up and handled specially
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * both for XPCOM and Windows. It is the responsibility of the caller to
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * take care of not running the loop again in a way which will hang. */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync postEvent(NULL);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return VINF_SUCCESS;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync}
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/**
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Posts an event to this event loop asynchronously.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync *
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @param event the event to post, must be allocated using |new|
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * @return TRUE if successful and false otherwise
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsyncBOOL NativeEventQueue::postEvent(NativeEvent *pEvent)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync{
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#ifndef VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync /* Note! The event == NULL case is duplicated in vboxapi/PlatformMSCOM::interruptWaitEvents(). */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync BOOL fRc = PostThreadMessage(mThreadId, WM_USER, (WPARAM)pEvent, EVENTQUEUE_WIN_LPARAM_MAGIC);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (!fRc)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync static int s_cBitchedAboutFullNativeEventQueue = 0;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if ( GetLastError() == ERROR_NOT_ENOUGH_QUOTA
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync && s_cBitchedAboutFullNativeEventQueue < 10)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync LogRel(("Warning: Asynchronous event queue (%p, thread %RI32) full, event (%p) not delivered (%d/10)\n",
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync this, mThreadId, pEvent, ++s_cBitchedAboutFullNativeEventQueue));
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync else
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync AssertFailed();
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return fRc;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#else // VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync if (!mEventQ)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return FALSE;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync try
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync MyPLEvent *pMyEvent = new MyPLEvent(pEvent);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync mEventQ->InitEvent(pMyEvent, this, com::NativeEventQueue::plEventHandler,
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync com::NativeEventQueue::plEventDestructor);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync HRESULT rc = mEventQ->PostEvent(pMyEvent);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return NS_SUCCEEDED(rc);
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync catch (std::bad_alloc &ba)
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync {
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync AssertMsgFailed(("Out of memory while allocating memory for event=%p: %s\n",
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync pEvent, ba.what()));
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync }
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return FALSE;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#endif // VBOX_WITH_XPCOM
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync}
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/**
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Get select()'able selector for this event queue.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * This will return -1 on platforms and queue variants not supporting such
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * functionality.
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync */
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsyncint NativeEventQueue::getSelectFD()
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync{
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#ifdef VBOX_WITH_XPCOM
6976ecae1d524fa439cc9aca14b612b262557cbevboxsync return mEventQ->GetEventQueueSelectFD();
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#else
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync return -1;
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#endif
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync}
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync}
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync/* namespace com */