SessionImpl.cpp revision 677833bc953b6cb418c701facbdcf4aa18d6c44e
0N/A * VBox Client Session COM Class implementation 0N/A * Copyright (C) 2006 InnoTek Systemberatung GmbH 0N/A * This file is part of VirtualBox Open Source Edition (OSE), as 0N/A * you can redistribute it and/or modify it under the terms of the GNU 0N/A * General Public License as published by the Free Software Foundation, 0N/A * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE 0N/A * distribution. VirtualBox OSE is distributed in the hope that it will 0N/A * be useful, but WITHOUT ANY WARRANTY of any kind. 0N/A * If you received this file as part of a commercial VirtualBox 0N/A * distribution, then only the terms of your commercial VirtualBox 553N/A * license agreement apply instead of the previous paragraph. 0N/A/** VM IPC mutex holder thread */ * Local macro to check whether the session is open and return an error if not. * @note Don't forget to do |Auto[Reader]Lock alock (this);| before using this tr (
"The session is not open")); \
// constructor / destructor ///////////////////////////////////////////////////////////////////////////// uninit (
true /* aFinalRelease */);
///////////////////////////////////////////////////////////////////////////// * Initializes the Session object. /* Enclose the state transition NotReady->InInit->Ready */ /* Confirm a successful initialization when it's the case */ * Uninitializes the Session object. * @note Locks this object for writing. /* Enclose the state transition Ready->InUninit->NotReady */ ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// /* close() needs write lock */ return close (
false /* aFinalRelease */,
false /* aFromServer */);
// IInternalSessionControl methods ///////////////////////////////////////////////////////////////////////////// (
"This is not a direct session!\n"),
E_FAIL);
* A special case: the server informs us that this session has been * passed to IVirtualBox::OpenRemoteSession() so this session will * become remote (but not existing) when AssignRemoteMachine() is /* query IInternalMachineControl interface */ * Reference the VirtualBox object to ensure the server is up * until the session is closed /* query IInternalMachineControl interface */ // currently, the remote session returns the same machine and // console objects as the direct session, thus giving the // (remote) client full control over the direct session. For the // console, it is the desired behavior (the ability to control // VM execution is a must for the remote session). What about // the machine object, we may want to prevent the remote client // from modifying machine data. In this case, we must: // 1) assign the Machine object (instead of the SessionMachine // object that is passed to this method) to mRemoteMachine; // 2) remove GetMachine() property from the IConsole interface // because it always returns the SessionMachine object // (alternatively, we can supply a separate IConsole // implementation that will return the Machine object in // response to GetMachine()). * Reference the VirtualBox object to ensure the server is up * until the session is closed * RemoteSession type can be already set by AssignMachine() when its * argument is NULL (a special case) * We might have already entered Session::uninit() at this point, so * return silently (not interested in the state change during uninit) rc =
close (
false /* aFinalRelease */,
true /* aFromServer */);
* We might have already entered Session::uninit() at this point, /////////////////////////////////////////////////////////////////////////////// * Closes the current session. * @param aFinalRelease called as a result of FinalRelease() * @param aFromServer called as a result of Uninitialize() * @note To be called only from #uninit(), #Close() or #Uninitialize(). * @note Locks this object for writing. /* The session object is going to be uninitialized by the client before * it has been assigned a direct console of the machine the client * requested to open a remote session to using IVirtualBox:: * openRemoteSession(). Theoretically it should not happen because * openRemoteSession() doesn't return control to the client until the * procedure is fully complete, so assert here. */ /* go to the closing state */ * We trigger OnSessionEnd() only when the session closes itself using * Close(). Note that if isFinalRelease = TRUE here, this means that * the client process has already initialized the termination procedure * without issuing Close() and the IPC channel is no more operational -- * so we cannot call the server's method (it will definitely fail). The * server will instead simply detect the abnormal client death (since * OnSessionEnd() is not called) and reset the machine state to Aborted. * while waiting for OnSessionEnd() to complete one of our methods * can be called by the server (for example, Uninitialize(), if the * direct session has initiated a closure just a bit before us) so * we need to release the lock to avoid deadlocks. The state is already * SessionState_SessionClosing here, so it's safe. * If we get E_UNEXPECTED this means that the direct session has already * been closed, we're just too late with our notification and nothing more * Wait for the server to grab the semaphore and destroy the session * machine (allowing us to open a new session with the same machine * once this method returns) /* release the VirtualBox instance as the very last step */ /** @note To be called only from #AssignMachine() */ /* open the IPC semaphore based on the sessionId and try to grab it */ * Since Session is an MTA object, this method can be executed on * any thread, and this thread will not necessarily match the thread on * which close() will be called later. Therefore, we need a separate * thread to hold the IPC mutex and then release it in close(). data [
2] = 0;
/* will get an output from the thread */ /* create the thread to hold the IPC mutex until signalled to release it */ /* wait until thread init is completed */ /* memorize the event sem we should signal in close() */ (
"Cannot open IPC semaphore, errno=%d",
errno),
(
"Cannot grab IPC semaphore, errno=%d",
errno),
/** @note To be called only from #close() */ /* release the IPC semaphore */ * say the thread holding the IPC mutex to release it; * it will close mIPCSem handle /* wait for the thread to finish */ /** VM IPC mutex holder thread */ /* signal we're done with init */ /* wait until we're signaled to release the IPC mutex */ /* release the IPC mutex */ LogFlow ((
"IPCMutexHolderThread(): releasing IPC mutex...\n"));