VirtualBox

Ignore:
Timestamp:
Sep 28, 2020 2:59:10 PM (4 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:9653: Extending UIMainEventListener with possibility to provide listener object with escape event types which should command listener to shutdown corresponding thread properly; Besides that, if no listening thread remain, listener will notify parent about listening was effectively finished and it's safe to perform cleanup.

Location:
trunk/src/VBox/Frontends/VirtualBox/src/globals
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMainEventListener.cpp

    r86322 r86323  
    8181
    8282    /** Constructs Main events listener thread redirecting events from @a comSource to @a comListener.
    83       * @param  comSource    Brings event source we are creating this thread for.
    84       * @param  comListener  Brings event listener we are creating this thread for. */
     83      * @param  comSource         Brings event source we are creating this thread for.
     84      * @param  comListener       Brings event listener we are creating this thread for.
     85      * @param  escapeEventTypes  Brings a set of escape event types which commands this thread to finish. */
    8586    UIMainEventListeningThread(const CEventSource &comSource,
    86                                const CEventListener &comListener);
     87                               const CEventListener &comListener,
     88                               const QSet<KVBoxEventType> &escapeEventTypes);
    8789    /** Destructs Main events listener thread. */
    8890    virtual ~UIMainEventListeningThread() /* override */;
     
    104106    /** Holds the Main event listener reference. */
    105107    CEventListener        m_comListener;
     108    /** Holds a set of event types this thread should finish job on. */
     109    QSet<KVBoxEventType>  m_escapeEventTypes;
    106110
    107111    /** Holds the mutex instance which protects thread access. */
     
    117121
    118122UIMainEventListeningThread::UIMainEventListeningThread(const CEventSource &comSource,
    119                                                        const CEventListener &comListener)
     123                                                       const CEventListener &comListener,
     124                                                       const QSet<KVBoxEventType> &escapeEventTypes)
    120125    : m_comSource(comSource)
    121126    , m_comListener(comListener)
     127    , m_escapeEventTypes(escapeEventTypes)
    122128    , m_fShutdown(false)
    123129{
     
    162168                LogRel(("GUI: UIMainEventListener/ThreadRun: EventProcessed set for waitable event\n"));
    163169            }
     170
     171            /* Check whether we should finish our job on this event: */
     172            if (m_escapeEventTypes.contains(comEvent.GetType()))
     173                setShutdown(true);
    164174        }
    165175    }
     
    206216
    207217void UIMainEventListener::registerSource(const CEventSource &comSource,
    208                                          const CEventListener &comListener)
     218                                         const CEventListener &comListener,
     219                                         const QSet<KVBoxEventType> &escapeEventTypes /* = QSet<KVBoxEventType>() */)
    209220{
    210221    /* Make sure source and listener are valid: */
     
    213224
    214225    /* Create thread for passed source: */
    215     UIMainEventListeningThread *pThread = new UIMainEventListeningThread(comSource, comListener);
     226    UIMainEventListeningThread *pThread = new UIMainEventListeningThread(comSource, comListener, escapeEventTypes);
    216227    if (pThread)
    217228    {
     229        /* Listen for thread finished signal: */
     230        connect(pThread, &UIMainEventListeningThread::finished,
     231                this, &UIMainEventListener::sltHandleThreadFinished);
    218232        /* Register & start it: */
    219233        m_threads << pThread;
     
    224238void UIMainEventListener::unregisterSources()
    225239{
     240    /* Stop listening for thread finished thread signals,
     241     * we are about to destroy these threads anyway: */
     242    foreach (UIMainEventListeningThread *pThread, m_threads)
     243        disconnect(pThread, &UIMainEventListeningThread::finished,
     244                   this, &UIMainEventListener::sltHandleThreadFinished);
     245
    226246    /* Wipe out the threads: */
    227247    /** @todo r=bird: The use of qDeleteAll here is unsafe because it won't take
     
    576596}
    577597
     598void UIMainEventListener::sltHandleThreadFinished()
     599{
     600    /* We have received a signal about thread finished, that means we were
     601     * patiently waiting for it, instead of killing UIMainEventListener object. */
     602    UIMainEventListeningThread *pSender = qobject_cast<UIMainEventListeningThread*>(sender());
     603    AssertPtrReturnVoid(pSender);
     604
     605    /* We should remove corresponding thread from the list: */
     606    const int iIndex = m_threads.indexOf(pSender);
     607    delete m_threads.value(iIndex);
     608    m_threads.removeAt(iIndex);
     609
     610    /* And notify listeners we have really finished: */
     611    if (m_threads.isEmpty())
     612        emit sigListeningFinished();
     613}
     614
    578615#include "UIMainEventListener.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMainEventListener.h

    r86322 r86323  
    2626#include <QObject>
    2727#include <QRect>
     28#include <QSet>
    2829
    2930/* GUI includes: */
     
    7172
    7273signals:
     74
     75    /** @name General signals
     76      * @{ */
     77        /** Notifies about listening has finished. */
     78        void sigListeningFinished();
     79    /** @} */
    7380
    7481    /** @name VirtualBoxClient related signals
     
    210217
    211218    /** Registers event source for passive event listener by creating a listening thread.
    212       * @param  comSource    Brings event source we are creating listening thread for.
    213       * @param  comListener  Brings event listener we are creating listening thread for. */
     219      * @param  comSource         Brings event source we are creating listening thread for.
     220      * @param  comListener       Brings event listener we are creating listening thread for.
     221      * @param  escapeEventTypes  Brings a set of escape event types which commands listener to finish. */
    214222    void registerSource(const CEventSource &comSource,
    215                         const CEventListener &comListener);
     223                        const CEventListener &comListener,
     224                        const QSet<KVBoxEventType> &escapeEventTypes = QSet<KVBoxEventType>());
    216225    /** Unregisters event sources. */
    217226    void unregisterSources();
     
    222231    /** Holds the list of threads handling passive event listening. */
    223232    QList<UIMainEventListeningThread*> m_threads;
     233
     234private slots:
     235
     236    /** Handles thread finished signal. */
     237    void sltHandleThreadFinished();
    224238};
    225239
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette