EventQueue.cpp revision 0077880aee88240fe71ee503ce96ecaaddc67657
/* $Id$ */
/** @file
* Event queue class declaration.
*/
/*
* Copyright (C) 2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/** @todo Adapt / update documentation! */
#include "VBox/com/EventQueue.h"
#include <new> /* For bad_alloc. */
#include <iprt/semaphore.h>
namespace com
{
// EventQueue class
////////////////////////////////////////////////////////////////////////////////
EventQueue::EventQueue(void)
: mShutdown(false)
{
}
EventQueue::~EventQueue(void)
{
{
}
}
/**
* Process events pending on this event queue, and wait up to given timeout, if
* nothing is available.
*
* Must be called on same thread this event queue was created on.
*
* @param cMsTimeout The timeout specified as milliseconds. Use
* RT_INDEFINITE_WAIT to wait till an event is posted on the
* queue.
*
* @returns VBox status code
* @retval VINF_SUCCESS if one or more messages was processed.
* @retval VERR_TIMEOUT if cMsTimeout expired.
* @retval VERR_INVALID_CONTEXT if called on the wrong thread.
* @retval VERR_INTERRUPTED if interruptEventQueueProcessing was called.
* On Windows will also be returned when WM_QUIT is encountered.
* On Darwin this may also be returned when the native queue is
* @retval VINF_INTERRUPTED if the native system call was interrupted by a
* an asynchronous event delivery (signal) or just felt like returning
* out of bounds. On darwin it will also be returned if the queue is
* stopped.
*/
{
bool fWait;
if (RT_SUCCESS(rc))
{
if (fWait)
{
}
}
else
{
fWait = false;
}
if (fWait)
{
if (RT_SUCCESS(rc))
}
if (RT_SUCCESS(rc))
{
if (ASMAtomicReadBool(&mShutdown))
{
return VERR_INTERRUPTED;
}
if (RT_SUCCESS(rc))
{
{
if (RT_SUCCESS(rc))
}
else
{
if (RT_SUCCESS(rc))
}
}
}
return rc;
}
/**
* Interrupt thread waiting on event queue processing.
*
* Can be called on any thread.
*
* @returns VBox status code.
*/
int EventQueue::interruptEventQueueProcessing(void)
{
ASMAtomicWriteBool(&mShutdown, true);
return RTSemEventSignal(mSemEvent);
}
/**
* Posts an event to this event loop asynchronously.
*
* @param event the event to post, must be allocated using |new|
* @return TRUE if successful and false otherwise
*/
{
if (RT_SUCCESS(rc))
{
try
{
if (pEvent)
{
}
else /* No locking, since we're already in our crit sect. */
mShutdown = true;
{
static int s_cBitchedAboutLotEvents = 0;
if (s_cBitchedAboutLotEvents < 10)
LogRel(("Warning: Event queue received lots of events (%zu), expect delayed event handling (%d/10)\n",
}
/* Leave critical section before signalling event. */
if (RT_SUCCESS(rc))
{
}
}
{
rc = VERR_NO_MEMORY;
}
if (RT_FAILURE(rc))
{
}
}
}
}
/* namespace com */