VirtualBox

source: vbox/trunk/src/VBox/HostServices/common/client.cpp@ 75829

Last change on this file since 75829 was 75737, checked in by vboxsync, 6 years ago

HGCM: Replace C++-style inline members on VBOXHGCMSVCPARM with simple functions.
bugref:9172: Shared folder performance tuning
Changes in bugref:9172 caused a build regression on Ubuntu 18.10 due to the
use of RT_ZERO on a structure containing an embedded VBOXHGCMSVCPARM, as
VBOXHGCMSVCPARM had member functions and was therefore not a simple plain-
old-data structure. Rather than just doing the sensible thing and zeroing
it in a different way, I converted the inline member getters and setters to
standard inline C functions, including fixing callers. Actually I had planned
this for some time, as the member function use seemed a bit gratuitous in
hindsight.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.0 KB
Line 
1/** @file
2 * Base class for a host-guest service.
3 */
4
5/*
6 * Copyright (C) 2011-2018 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 */
16
17#include <VBox/log.h>
18#include <VBox/hgcmsvc.h>
19
20#include <iprt/assert.h>
21#include <iprt/alloc.h>
22#include <iprt/cpp/utils.h>
23
24#include <VBox/HostServices/Service.h>
25
26using namespace HGCM;
27
28Client::Client(uint32_t uClientID)
29 : m_uClientID(uClientID)
30 , m_uProtocolVer(0)
31 , m_fDeferred(false)
32{
33 RT_ZERO(m_Deferred);
34 RT_ZERO(m_SvcCtx);
35}
36
37Client::~Client(void)
38{
39
40}
41
42/**
43 * Completes a guest call by returning the control back to the guest side,
44 * together with a status code, internal version.
45 *
46 * @returns IPRT status code.
47 * @param hHandle Call handle to complete guest call for.
48 * @param rcOp Return code to return to the guest side.
49 */
50int Client::completeInternal(VBOXHGCMCALLHANDLE hHandle, int rcOp)
51{
52 LogFlowThisFunc(("uClientID=%RU32\n", m_uClientID));
53
54 if ( m_SvcCtx.pHelpers
55 && m_SvcCtx.pHelpers->pfnCallComplete)
56 {
57 m_SvcCtx.pHelpers->pfnCallComplete(hHandle, rcOp);
58
59 reset();
60 return VINF_SUCCESS;
61 }
62
63 return VERR_NOT_AVAILABLE;
64}
65
66/**
67 * Resets the client's internal state.
68 */
69void Client::reset(void)
70{
71 m_fDeferred = false;
72
73 RT_ZERO(m_Deferred);
74}
75
76/**
77 * Completes a guest call by returning the control back to the guest side,
78 * together with a status code.
79 *
80 * @returns IPRT status code.
81 * @param hHandle Call handle to complete guest call for.
82 * @param rcOp Return code to return to the guest side.
83 */
84int Client::Complete(VBOXHGCMCALLHANDLE hHandle, int rcOp /* = VINF_SUCCESS */)
85{
86 return completeInternal(hHandle, rcOp);
87}
88
89/**
90 * Completes a deferred guest call by returning the control back to the guest side,
91 * together with a status code.
92 *
93 * @returns IPRT status code. VERR_INVALID_STATE if the client is not in deferred mode.
94 * @param rcOp Return code to return to the guest side.
95 */
96int Client::CompleteDeferred(int rcOp)
97{
98 if (m_fDeferred)
99 {
100 Assert(m_Deferred.hHandle != NULL);
101
102 int rc = completeInternal(m_Deferred.hHandle, rcOp);
103 if (RT_SUCCESS(rc))
104 m_fDeferred = false;
105
106 return rc;
107 }
108
109 AssertMsg(m_fDeferred, ("Client %RU32 is not in deferred mode\n", m_uClientID));
110 return VERR_INVALID_STATE;
111}
112
113/**
114 * Returns the HGCM call handle of the client.
115 *
116 * @returns HGCM handle.
117 */
118VBOXHGCMCALLHANDLE Client::GetHandle(void) const
119{
120 return m_Deferred.hHandle;
121}
122
123/**
124 * Returns the HGCM call handle of the client.
125 *
126 * @returns HGCM handle.
127 */
128uint32_t Client::GetMsgType(void) const
129{
130 return m_Deferred.uType;
131}
132
133uint32_t Client::GetMsgParamCount(void) const
134{
135 return m_Deferred.cParms;
136}
137
138/**
139 * Returns the client's (HGCM) ID.
140 *
141 * @returns The client's (HGCM) ID.
142 */
143uint32_t Client::GetClientID(void) const
144{
145 return m_uClientID;
146}
147
148/**
149 * Returns the client's used protocol version.
150 *
151 * @returns Protocol version, or 0 if not set.
152 */
153uint32_t Client::GetProtocolVer(void) const
154{
155 return m_uProtocolVer;
156}
157
158/**
159 * Returns whether the client currently is in deferred mode or not.
160 *
161 * @returns \c True if in deferred mode, \c False if not.
162 */
163bool Client::IsDeferred(void) const
164{
165 return m_fDeferred;
166}
167
168/**
169 * Set the client's status to deferred, meaning that it does not return to the caller
170 * until CompleteDeferred() has been called.
171 */
172void Client::SetDeferred(VBOXHGCMCALLHANDLE hHandle, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
173{
174 LogFlowThisFunc(("uClient=%RU32\n", m_uClientID));
175
176 AssertMsg(m_fDeferred == false, ("Client already in deferred mode\n"));
177 m_fDeferred = true;
178
179 m_Deferred.hHandle = hHandle;
180 m_Deferred.uType = u32Function;
181 m_Deferred.cParms = cParms;
182 m_Deferred.paParms = paParms;
183}
184
185/**
186 * Sets the client's protocol version. The protocol version is purely optional and bound
187 * to a specific HGCM service.
188 *
189 * @param uVersion Version number to set.
190 */
191void Client::SetProtocolVer(uint32_t uVersion)
192{
193 m_uProtocolVer = uVersion;
194}
195
196/**
197 * Sets the HGCM service context.
198 *
199 * @param SvcCtx Service context to set.
200 */
201void Client::SetSvcContext(const VBOXHGCMSVCTX &SvcCtx)
202{
203 m_SvcCtx = SvcCtx;
204}
205
206/**
207 * Sets the deferred parameters to a specific message type and
208 * required parameters. That way the client can re-request that message with
209 * the right amount of parameters from the service.
210 *
211 * @returns IPRT status code.
212 * @param uMsg Message type (number) to set.
213 * @param cParms Number of parameters the message needs.
214 */
215int Client::SetDeferredMsgInfo(uint32_t uMsg, uint32_t cParms)
216{
217 if (m_fDeferred)
218 {
219 if (m_Deferred.cParms < 2)
220 return VERR_INVALID_PARAMETER;
221
222 AssertPtrReturn(m_Deferred.paParms, VERR_BUFFER_OVERFLOW);
223
224 HGCMSvcSetU32(&m_Deferred.paParms[0], uMsg);
225 HGCMSvcSetU32(&m_Deferred.paParms[1], cParms);
226
227 return VINF_SUCCESS;
228 }
229
230 AssertFailed();
231 return VERR_INVALID_STATE;
232}
233
234/**
235 * Sets the deferred parameters to a specific message type and
236 * required parameters. That way the client can re-request that message with
237 * the right amount of parameters from the service.
238 *
239 * @returns IPRT status code.
240 * @param pMessage Message to get message type and required parameters from.
241 */
242int Client::SetDeferredMsgInfo(const Message *pMessage)
243{
244 AssertPtrReturn(pMessage, VERR_INVALID_POINTER);
245 return SetDeferredMsgInfo(pMessage->GetType(), pMessage->GetParamCount());
246}
247
Note: See TracBrowser for help on using the repository browser.

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