summaryrefslogtreecommitdiff
path: root/src/VBox/Additions/x11/VBoxClient/thread.h
blob: 8cd118ac522f4d55ace9bcbe4a66280d7a4b7a14 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/** @file
 *
 * VirtualBox additions client application: thread class.
 */

/*
 * Copyright (C) 2006-2010 Oracle Corporation
 *
 * This file is part of VirtualBox Open Source Edition (OSE), as
 * available from http://www.virtualbox.org. This file is free software;
 * you can redistribute it and/or modify it under the terms of the GNU
 * 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.
 */

#ifndef __Additions_client_thread_h
# define __Additions_client_thread_h

#include <iprt/thread.h>
#include <iprt/err.h>

#include <VBox/log.h>

class VBoxGuestThread;

/** Virtual parent class for thread functions for the VBoxGuestThread class. */
class VBoxGuestThreadFunction
{
public:
    // VBoxGuestThreadFunction(void);
    virtual ~VBoxGuestThreadFunction(void) {}
    /**
      * The actual thread function.
      *
      * @returns iprt status code as thread return value
      * @param pParent the VBoxGuestThread running this thread function
      */
    virtual int threadFunction(VBoxGuestThread *pPThread) = 0;
    /**
     * Send a signal to the thread function that it should exit.  This should not block.
     */
    virtual void stop(void) = 0;
};

/** C++ wrapper for VBox runtime threads. */
class VBoxGuestThread
{
private:
    // Private member variables
    /** The thread function for this thread */
    VBoxGuestThreadFunction *mFunction;
    /** The size of the stack for the new thread.  Use 0 for the default stack size. */
    size_t mStack;
    /** The thread type. Used for deciding scheduling attributes of the thread. */
    RTTHREADTYPE mType;
    /** Flags of the RTTHREADFLAGS type (ORed together). */
    unsigned mFlags;
    /** Thread name */
    const char *mName;
    /** The VBox runtime thread handle. */
    RTTHREAD mSelf;
    /** Is the thread currently running? */
    volatile bool mRunning;
    /** Should the thread be stopped? */
    volatile bool mExit;

    // Typedefs
    /** Ourselves, for use in the thread function. */
    typedef VBoxGuestThread *PSELF;
public:
    /**
     * Initialise the class.
     * @param   pFunction   the thread function for this thread
     * @param   cbStack     The size of the stack for the new thread.
     *                      Use 0 for the default stack size.
     * @param   enmType     The thread type. Used for deciding scheduling attributes
     *                      of the thread.
     * @param   fFlags      Flags of the RTTHREADFLAGS type (ORed together).
     * @param   pszName     Thread name.
     */
    VBoxGuestThread(VBoxGuestThreadFunction *pFunction, size_t cbStack, RTTHREADTYPE enmType,
                    unsigned fFlags, const char *pszName)
    {
        mFunction = pFunction;
        mStack = cbStack;
        mType = enmType;
        mFlags = fFlags;
        mName = pszName;
        mSelf = NIL_RTTHREAD;
        mRunning = false;
        mExit = false;
    }
    /** Stop the thread using its stop method and get the exit value.
     * @returns iprt status code
     * @param   cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
     *                              an indefinite wait.  Only relevant if the thread is
     *                              waitable.
     * @param   prc             Where to store the return code of the thread. Optional.
     */
    int stop(RTMSINTERVAL cMillies, int *prc);

    /** Destroy the class, stopping the thread if necessary. */
    ~VBoxGuestThread(void);

    /** Return the VBox runtime thread handle. */
    RTTHREAD getSelf(void) { return mSelf; }

    /** Start the thread. */
    int start(void);

    /** Yield the CPU */
    bool yield(void);

    /** Is the thread running? */
    bool isRunning(void) { return mRunning; }

    /** Should the thread function exit? */
    bool isStopping(void) { return mExit; }
private:
    // Copying or assigning a thread object is not sensible
    VBoxGuestThread(const VBoxGuestThread&);
    VBoxGuestThread& operator=(const VBoxGuestThread&);

    // Member functions
    /** The "real" thread function for the VBox runtime. */
    static DECLCALLBACK(int) threadFunction(RTTHREAD self, void *pvUser);
};

#endif /* __Additions_client_thread_h not defined */