summaryrefslogtreecommitdiffstats
path: root/src/VBox/Main/include/HGCMObjects.h
blob: a651d3c3d819fc0e00950f1c03fbb015776d5341 (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
132
133
134
135
136
137
138
/* $Id: HGCMObjects.h $ */
/** @file
 * HGCMObjects - Host-Guest Communication Manager objects header.
 */

/*
 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
 *
 * This file is part of VirtualBox base platform packages, as
 * available from https://www.virtualbox.org.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, in version 3 of the
 * License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <https://www.gnu.org/licenses>.
 *
 * SPDX-License-Identifier: GPL-3.0-only
 */

#ifndef MAIN_INCLUDED_HGCMObjects_h
#define MAIN_INCLUDED_HGCMObjects_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif

#include <iprt/assert.h>
#include <iprt/avl.h>
#include <iprt/critsect.h>
#include <iprt/asm.h>

class HGCMObject;

typedef struct ObjectAVLCore
{
    AVLU32NODECORE AvlCore;
    HGCMObject *pSelf;
} ObjectAVLCore;

typedef enum
{
    HGCMOBJ_CLIENT,
    HGCMOBJ_THREAD,
    HGCMOBJ_MSG,
    HGCMOBJ_SizeHack   = 0x7fffffff
} HGCMOBJ_TYPE;


/**
 * A referenced object.
 */
class HGCMReferencedObject
{
    private:
        int32_t volatile m_cRefs;
        HGCMOBJ_TYPE     m_enmObjType;

    protected:
        virtual ~HGCMReferencedObject()
        {}

    public:
        HGCMReferencedObject(HGCMOBJ_TYPE enmObjType)
            : m_cRefs(0)   /** @todo change to 1! */
            , m_enmObjType(enmObjType)
        {}

        void Reference()
        {
            int32_t cRefs = ASMAtomicIncS32(&m_cRefs);
            NOREF(cRefs);
            Log(("Reference(%p/%d): cRefs = %d\n", this, m_enmObjType, cRefs));
        }

        void Dereference()
        {
            int32_t cRefs = ASMAtomicDecS32(&m_cRefs);
            Log(("Dereference(%p/%d): cRefs = %d \n", this, m_enmObjType, cRefs));
            AssertRelease(cRefs >= 0);

            if (cRefs)
            { /* likely */ }
            else
                delete this;
        }

        HGCMOBJ_TYPE Type()
        {
            return m_enmObjType;
        }
};


class HGCMObject : public HGCMReferencedObject
{
    private:
        friend uint32_t hgcmObjMake(HGCMObject *pObject, uint32_t u32HandleIn);

        ObjectAVLCore   m_core;

    protected:
        virtual ~HGCMObject()
        {}

    public:
        HGCMObject(HGCMOBJ_TYPE enmObjType)
            : HGCMReferencedObject(enmObjType)
        {}

        uint32_t Handle()
        {
            return (uint32_t)m_core.AvlCore.Key;
        }
};

int         hgcmObjInit();
void        hgcmObjUninit();

uint32_t    hgcmObjGenerateHandle(HGCMObject *pObject);
uint32_t    hgcmObjAssignHandle(HGCMObject *pObject, uint32_t u32Handle);

void        hgcmObjDeleteHandle(uint32_t handle);

HGCMObject *hgcmObjReference(uint32_t handle, HGCMOBJ_TYPE enmObjType);
void        hgcmObjDereference(HGCMObject *pObject);

uint32_t    hgcmObjQueryHandleCount();
void        hgcmObjSetHandleCount(uint32_t u32HandleCount);


#endif /* !MAIN_INCLUDED_HGCMObjects_h */