VirtualBoxImpl.cpp revision 1acc6ad8398d9bdaa1e7480ed46955f6c578d825
* Main VirtualBox data structure. * @note |const| members are persistent during lifetime so can be accessed // const data members not requiring locking // VirtualBox main settings file // const objects not requiring locking #
endif /* VBOX_WITH_RESOURCE_USAGE_API */ // Each of the following lists use a particular lock handle that protects the // list as a whole. As opposed to version 3.1 and earlier, these lists no // longer need the main VirtualBox object lock, but only the respective list // lock. In each case, the locking order is defined that the list must be // requested before object locks of members of the lists (see the order definitions // in AutoLock.h; e.g. LOCKCLASS_LISTOFMACHINES before LOCKCLASS_MACHINEOBJECT). // All the media lists are protected by the following locking handle: // the hard disks map is an additional map sorted by UUID for quick lookup // and contains ALL hard disks (base and differencing); it is protected by // the same lock as the other media lists above // list of pending machine renames (also protected by media tree lock; // see VirtualBox::rememberMachineNameChangeForMedia()) // the following are data for the client watcher thread // the following are data for the async event thread // constructor / destructor ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// * Initializes the VirtualBox object. * @return COM result code /* Enclose the state transition NotReady->InInit->Ready */ /* Locking this object for writing during init sounds a bit paradoxical, * but in the current locking mess this avoids that some code gets a * read lock and later calls code which wants the same write lock. */ // allocate our instance data LogFlow ((
"===========================================================\n"));
/* Get the VirtualBox home directory. */ tr(
"Could not create the VirtualBox home directory '%s' (%Rrc)"),
// load and parse VirtualBox.xml; this will throw on XML or logic errors // this is thrown by the XML backend if the RTOpen() call fails; // only if the main settings file does not exist, create it, // if there's something more serious, then do fail! /* create the performance collector object BEFORE host */ #
endif /* VBOX_WITH_RESOURCE_USAGE_API */ /* create the host object early, machines will need it */ /* create the system properties object, someone may need it too */ /* guest OS type objects, needed by machines */ /* all registered media, needed by machines */ /* we assume that error info is set by the thrower */ /* start the client watcher thread */ /* start the async event handler thread */ /* wait until the thread sets m->pAsyncEventQ */ /* Confirm a successful initialization when it's the case */ LogFlow ((
"===========================================================\n"));
xmlHD);
// XML data; this recurses to processes the children /* Enclose the state transition Ready->InUninit->NotReady */ LogFlow ((
"===========================================================\n"));
/* tell all our child objects we've been uninitialized */ /* Note that we release singleton children after we've all other children. * In some cases this is important because these other children may use * some resources of the singletons which would prevent them from * uninitializing (as for example, mSystemProperties which owns * MediumFormat objects which Medium objects refer to) */ #
endif /* VBOX_WITH_RESOURCE_USAGE_API */ /* release all callbacks */ /* signal to exit the event loop */ * Wait for thread termination (only if we've successfully posted /* signal the client watcher thread */ /* wait for the termination */ // clean up our instance data /* Unload hard disk plugin backends. */ LogFlow ((
"===========================================================\n"));
// IVirtualBox properties ///////////////////////////////////////////////////////////////////////////// /* mHomeDir is const and doesn't need a lock */ /* mCfgFile.mName is const and doesn't need a lock */ /* mHost is const, no need to lock */ /* mSystemProperties is const, no need to lock */ /* protect mProgressOperations */ #
endif /* RT_OS_WINDOWS */ /* mPerformanceCollector is const, no need to lock */ #
else /* !VBOX_WITH_RESOURCE_USAGE_API */#
endif /* !VBOX_WITH_RESOURCE_USAGE_API */ /* compiled-in firmware */ /* compiled-in firmware */ /** @todo: account for version in the URL */ /* Assume single record per firmware type */ ///////////////////////////////////////////////////////////////////////////// /** @note Locks mSystemProperties object for reading. */ /** @todo tighten checks on aId? */ /* Compose the settings file name using the following scheme: * <base_folder>/<machine_name>/<machine_name>.xml * If a non-null and non-empty base folder is specified, the default * machine folder will be used as a base folder. /* we use the non-full folder value below to keep the path relative */ /* create a new object */ /* Create UUID if an empty one was specified. */ /* initialize the machine object */ /* set the return value */ /** @todo tighten checks on aId? */ /* append the default extension if none */ /* create a new object */ /* Create UUID if an empty one was specified. */ /* initialize the machine object */ /* set the return value */ /* create a new object */ /* initialize the machine object */ /* set the return value */ /** @note Locks objects! */ /* We can safely cast child to Machine * here because only Machine * implementations of IMachine can be among our children. */ /** @note Locks objects! */ /* the below will set *aMachine to NULL if machine is null */ /** @note Locks this object for reading, then some machine objects for reading. */ /* start with not found */ /* skip inaccessible machines */ /* this will set (*machine) to NULL if machineObj is null */ tr(
"Could not find a registered machine named '%ls'"),
aName);
/** @note Locks objects! */ // find machine from the given ID // trySetRegistered needs VirtualBox object write lock /* remove from the collection of registered machines */ /* save the global registry */ /* return the unregistered machine to the caller */ /* we don't access non-const data members so no need to lock */ /* we don't access non-const data members so no need to lock */ /* Note that it's important to call uninit() on failure to register * because the differencing hard disk would have been already associated * with the parent and this association needs to be broken. */ /* the below will set *aHardDisk to NULL if hardDisk is null */ /* the below will set *aHardDisk to NULL if hardDisk is null */ /** @note Doesn't lock anything. */ /* generate an UUID if not specified */ /** @note Locks objects! */ /* the below will set *aDVDImage to NULL if image is null */ /** @note Locks objects! */ /* the below will set *aDVDImage to NULL if dvd is null */ /** @note Doesn't lock anything. */ /* generate an UUID if not specified */ /** @note Locks objects! */ /* the below will set *aFloppyImage to NULL if image is null */ /** @note Locks objects! */ /* the below will set *aFloppyImage to NULL if img is null */ /** @note Locks this object for reading. */ /* Old ID to new ID conversion table. See r39691 for a source */ L
"winnt4", L
"WindowsNT4",
L
"win2k", L
"Windows2000",
L
"win2k3", L
"Windows2003",
L
"winvista", L
"WindowsVista",
L
"win2k8", L
"Windows2008",
L
"fedoracore", L
"Fedora",
/* the rest is covered by the case-insensitive comparison */ /* first, look for a substitution */ tr(
"'%ls' is not a valid Guest OS type"),
* @note Locks this object for reading. * @note Locks this object for reading. /* start with nothing found */ /* return the result to caller (may be empty) */ * @note Locks this object for writing. // locking note: we only hold the read lock briefly to look up the old value, // then release it and call the onExtraCanChange callbacks. There is a small // chance of a race insofar as the callback might be called twice if two callers // change the same key at the same time, but that's a much better solution // than the deadlock we had here before. The actual changing of the extradata // is then performed under the write lock and race-free. // look up the old value first; if nothing's changed then we need not do anything // ask for permission from all listeners outside the locks; // onExtraDataCanChange() only briefly requests the VirtualBox // lock to copy the list of callbacks to invoke tr(
"Could not set extra data because someone refused the requested change of '%ls' to '%ls'%s%ls"),
// data is changing and change not vetoed: then write it out under the lock // creates a new key if needed /* save settings on success */ // fire notification outside the lock /* check the session state */ tr(
"The given session is already open or being opened"));
/* get the IInternalSessionControl interface */ * tell the client watcher thread to update the set of * machines that have open sessions /* check the session state */ tr(
"The given session is already open or being opened"));
/* get the IInternalSessionControl interface */ /* create a progress object */ Bstr (
tr (
"Spawning session")),
FALSE /* aCancelable */);
/* signal the client watcher thread */ /* check the session state */ tr(
"The given session is already open or being opened"));
/* get the IInternalSessionControl interface */ * @note Locks this object for writing. #
if 0
/** @todo r=bird,r=pritesh: must check that the interface id match correct or we might screw up with old code! */ * @note Locks this object for writing. // public methods only for internal purposes ///////////////////////////////////////////////////////////////////////////// * Posts an event to the event queue that is processed asynchronously * Posting events to the dedicated event queue is useful to perform secondary * actions outside any object locks -- for example, to iterate over a list * of callbacks and inform them about some change caused by some object's * @param event event to post * (must be allocated using |new|, will be deleted automatically * by the event thread after processing) * @note Doesn't lock any object. "the event is discarded!\n",
* Adds a progress to the global collection of pending operations. * Usually gets called upon progress object initialization. * @param aProgress Operation to add to the collection. * @note Doesn't lock objects. /* protect mProgressOperations */ * Removes the progress from the global collection of pending operations. * Usually gets called upon progress completion. * @param aId UUID of the progress operation to remove * @note Doesn't lock objects. /* protect mProgressOperations */ * Helper method that starts a worker thread that: * - creates a pipe communication channel using SVCHlpClient; * - starts an SVC Helper process that will inherit this channel; * - executes the supplied function by passing it the created SVCHlpClient * and opened instance to communicate to the Helper process and the given * The user function is supposed to communicate to the helper process * using the \a aClient argument to do the requested job and optionally expose * the progress through the \a aProgress object. The user function should never * call notifyComplete() on it: this will be done automatically using the * result code returned by the function. * Before the user function is started, the communication channel passed to * the \a aClient argument is fully set up, the function should start using * its write() and read() methods directly. * The \a aVrc parameter of the user function may be used to return an error * code if it is related to communication errors (for example, returned by * the SVCHlpClient members when they fail). In this case, the correct error * message using this value will be reported to the caller. Note that the * value of \a aVrc is inspected only if the user function itself returns * If a failure happens anywhere before the user function would be normally * called, it will be called anyway in special "cleanup only" mode indicated * by \a aClient, \a aProgress and \aVrc arguments set to NULL. In this mode, * all the function is supposed to do is to cleanup its aUser argument if * necessary (it's assumed that the ownership of this argument is passed to * the user function once #startSVCHelperClient() returns a success, thus * making it responsible for the cleanup). * After the user function returns, the thread will send the SVCHlpMsg::Null * message to indicate a process termination. * @param aPrivileged |true| to start the SVC Helper process as a privileged * user that can perform administrative tasks * @param aFunc user function to run * @param aUser argument to the user function * @param aProgress progress object that will track operation completion * @note aPrivileged is currently ignored (due to some unsolved problems in * Vista) and the process will be started as a normal (unprivileged) * @note Doesn't lock anything. /* create the SVCHelperClientThread() argument */ static_cast <
void *> (d.
get()),
/* d is now owned by SVCHelperClientThread(), so release it */ * Worker thread for startSVCHelperClient(). /* protect VirtualBox from uninitialization */ tr(
"Could not create the communication channel (%Rrc)"),
vrc);
/* get the path to the executable */ /* Attempt to start a privileged process using the Run As dialog */ /* hide excessive details in case of a frequent error * (pressing the Cancel button to close the Run As dialog) */ tr(
"Operation cancelled by the user"));
tr(
"Could not launch a privileged process '%s' (%Rrc)"),
tr(
"Could not launch a process '%s' (%Rrc)"),
exePath,
vrc);
/* wait for the client to connect */ /* start the user supplied function */ /* send the termination signal to the process anyway */ tr(
"Could not operate the communication channel (%Rrc)"),
vrc);
/* call the user function in the "cleanup only" mode * to let it free resources passed to in aUser */ #
endif /* RT_OS_WINDOWS */ * Sends a signal to the client watcher thread to rescan the set of machines * that have open sessions. * @note Doesn't lock anything. /* sent an update request */ * Adds the given child process ID to the list of processes to be reaped. * This call should be followed by #updateClientWatcher() to take the effect. /** Event for onMachineStateChange(), onMachineDataChange(), onMachineRegistered() */ LogFlow ((
"OnMachineDataChange: id={%RTuuid}\n",
id.
ptr()));
LogFlow ((
"OnMachineStateChange: id={%RTuuid}, state=%d\n",
LogFlow ((
"OnMachineRegistered: id={%RTuuid}, registered=%d\n",
* @note Doesn't lock any object. * @note Doesn't lock any object. * @note Locks this object for reading. /* if a call to this method fails for some reason (for ex., because * the other side is dead), we ensure allowChange stays true * (MS COM RPC implementation seems to zero all output vars before * issuing an IPC call or after a failure, so it's essential /** Event for onExtraDataChange() */ LogFlow ((
"OnExtraDataChange: machineId={%RTuuid}, key='%ls', val='%ls'\n",
* @note Doesn't lock any object. * @note Doesn't lock any object. /** Event for onSessionStateChange() */ LogFlow ((
"OnSessionStateChange: machineId={%RTuuid}, sessionState=%d\n",
* @note Doesn't lock any object. /** Event for onSnapshotTaken(), onSnapshotRemoved() and onSnapshotChange() */ LogFlow ((
"OnSnapshotTaken: machineId={%RTuuid}, snapshotId={%RTuuid}\n",
LogFlow ((
"OnSnapshotDiscarded: machineId={%RTuuid}, snapshotId={%RTuuid}\n",
LogFlow ((
"OnSnapshotChange: machineId={%RTuuid}, snapshotId={%RTuuid}\n",
* @note Doesn't lock any object. * @note Doesn't lock any object. * @note Doesn't lock any object. /** Event for onGuestPropertyChange() */ LogFlow((
"OnGuestPropertyChange: machineId={%RTuuid}, name='%ls', value='%ls', flags='%ls'\n",
* @note Doesn't lock any object. * @note Locks this object for reading. /* unknown type must always be the first */ * Returns the list of opened machines (machines having direct sessions opened * by client processes) and optionally the list of direct session controls. * @param aMachines Where to put opened machines (will be empty if none). * @param aControls Where to put direct session controls (optional). * @note The returned lists contain smart pointers. So, clear it as soon as * it becomes no more necessary to release instances. * @note It can be possible that a session machine from the list has been * when accessing unprotected data directly. * @note Locks objects for reading. * Searches for a Machine object with the given ID in the collection * of registered machines. * if TRUE, the appropriate error info is set in case when the machine * where to store the found machine object (can be NULL) * S_OK when found or VBOX_E_OBJECT_NOT_FOUND when not found * @note Locks this object for reading. tr(
"Could not find a registered machine with UUID {%RTuuid}"),
* Searches for a Medium object with the given ID or location in the list of * registered hard disks. If both ID and location are specified, the first * object that matches either of them (not necessarily both) is returned. * @param aId ID of the hard disk (unused when NULL). * @param aLocation Full location specification (unused NULL). * @param aSetError If @c true , the appropriate error info is set in case * when the hard disk is not found. * @param aHardDisk Where to store the found hard disk object (can be NULL). * @return S_OK when found or E_INVALIDARG when not found. * @note Locks the media tree for reading. // we use the hard disks map, but it is protected by the // hard disk _list_ lock handle /* first, look up by UUID in the map if UUID is provided */ /* then iterate and search by location */ tr(
"Could not find a hard disk with UUID {%RTuuid} in the media registry ('%s')"),
tr(
"Could not find a hard disk with location '%ls' in the media registry ('%s')"),
* Searches for a Medium object with the given ID or location in the list of * registered DVD images. If both ID and file path are specified, the first * object that matches either of them (not necessarily both) is returned. * @param aId ID of the DVD image (unused when NULL). * @param aLocation Full path to the image file (unused when NULL). * @param aSetError If @c true, the appropriate error info is set in case when * the image is not found. * @param aImage Where to store the found image object (can be NULL). * @return S_OK when found or E_INVALIDARG when not found. * @note Locks the media tree for reading. tr(
"Invalid image file location '%ls' (%Rrc)"),
/* no AutoCaller, registered image life time is bound to this */ tr(
"Could not find a CD/DVD image with UUID {%RTuuid} in the media registry ('%s')"),
tr(
"Could not find a CD/DVD image with location '%ls' in the media registry ('%s')"),
* Searches for a Medium object with the given ID or location in the * collection of registered DVD images. If both ID and file path are specified, * the first object that matches either of them (not necessarily both) is * @param aId ID of the DVD image (unused when NULL). * @param aLocation Full path to the image file (unused when NULL). * @param aSetError If @c true, the appropriate error info is set in case when * the image is not found. * @param aImage Where to store the found image object (can be NULL). * @return S_OK when found or E_INVALIDARG when not found. * @note Locks the media tree for reading. tr(
"Invalid image file location '%ls' (%Rrc)"),
/* no AutoCaller, registered image life time is bound to this */ tr(
"Could not find a floppy image with UUID {%RTuuid} in the media registry ('%s')"),
tr(
"Could not find a floppy image with location '%ls' in the media registry ('%s')"),
/* Look for a GuestOSType object */ (
"Guest OS types array must be filled"));
tr(
"Guest OS type '%ls' is invalid"),
#
endif /* VBOX_WITH_RESOURCE_USAGE_API */ * Returns the default machine folder from the system properties * Returns the default hard disk folder from the system properties * Returns the default hard disk format from the system properties * Calculates the absolute path of the given path taking the VirtualBox home * directory as the current directory. * @param aPath Path to calculate the absolute path for. * @param aResult Where to put the result (used only on success, can be the * same Utf8Str instance as passed in @a aPath). * @note Doesn't lock any object. /* no need to lock since mHomeDir is const */ * Tries to calculate the relative path of the given absolute path using the * directory of the VirtualBox settings file as the base directory. * @param aPath Absolute path to calculate the relative path for. * @param aResult Where to put the result (used only when it's possible to * make a relative path from the given absolute path; otherwise * @note Doesn't lock any object. /* no need to lock since mHomeDir is const */ /* when assigning, we create a separate Utf8Str instance because both * aPath and aResult can point to the same memory location when this * func is called (if we just do aResult = aPath, aResult will be freed * first, and since its the same as aPath, an attempt to copy garbage ///////////////////////////////////////////////////////////////////////////// * Checks if there is a hard disk, DVD or floppy image with the given ID or * location already registered. * On return, sets @a aConflict to the string describing the conflicting medium, * or sets it to @c Null if no conflicting media is found. Returns S_OK in * either case. A failure is unexpected. * @param aId UUID to check. * @param aLocation Location to check. * @param aConflict Where to return parameters of the conflicting medium. * @note Locks the media tree and media objects for reading. /* Note: no AutoCaller since bound to this */ /* Note: no AutoCaller since bound to this */ /* Note: no AutoCaller since bound to this */ * Called from Machine::prepareSaveSettings() when it has detected * that a machine has been renamed. Such renames will require * updating the global media registry during the * VirtualBox::saveSettings() that follows later. * When a machine is renamed, there may well be media (in particular, * diff images for snapshots) in the global registry that will need * to have their paths updated. Before 3.2, Machine::saveSettings * used to call VirtualBox::saveSettings implicitly, which was both * unintuitive and caused locking order problems. Now, we remeber * such pending name changes with this method so that * VirtualBox::saveSettings() can process them properly. * Helper function to write out the configuration tree. * @note Caller must have locked the VirtualBox object for writing! // lock the lists while we're here // save actual machine registry entry // lock all media for the following; use a write lock because we're // modifying the PendingMachineRenamesList, which is protected by this // if a machine was renamed, then we'll need to refresh media paths // make a single list from the three media lists so we don't need three loops // with hard disks, we must use the map, not the list, because the list only has base images // done, don't do it again until we have more machine renames /* now copy the temp data to the config file under the VirtualBox lock */ // leave extra data alone, it's still in the config file /* host data (USB filters) */ // and write out the XML, still under the lock /* we assume that error info is set by the thrower */ * Helper to register the machine. * When called during VirtualBox startup, adds the given machine to the * collection of registered machines. Otherwise tries to mark the machine * as registered, and, if succeeded, adds it to the collection and * @note The caller must have added itself as a caller of the @a aMachine * object if calls this method not on VirtualBox startup. * @param aMachine machine to register tr(
"Registered machine with UUID {%RTuuid} ('%ls') already exists"),
/* add to the collection of registered machines */ * Remembers the given hard disk by storing it in the hard disk registry. * @param aHardDisk Hard disk object to remember. * @param pfNeedsSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true * by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed. * @note Caller must hold the media tree lock for writing; in addition, this locks @a aHardDisk for reading // caller must hold the media tree write lock tr(
"Cannot register the hard disk '%s' with UUID {%RTuuid} because a %s already exists in the media registry ('%s')"),
// store base (root) hard disks in the list // access the list directly because we already locked the list above // store all hard disks (even differencing images) in the map * Removes the given hard disk from the hard disk registry. * @param aHardDisk Hard disk object to remove. * @param pfNeedsSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true * by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed. * @note Caller must hold the media tree lock for writing; in addition, this locks @a aHardDisk for reading // caller must hold the media tree write lock // remove base (root) hard disks from the list // access the list directly because caller must have locked the list // remove all hard disks (even differencing images) from map * Remembers the given image by storing it in the CD/DVD or floppy image registry. * @param argImage Image object to remember. * @param argType Either DeviceType_DVD or DeviceType_Floppy. * @param pfNeedsSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true * by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed. * @note Caller must hold the media tree lock for writing; in addition, this locks @a argImage for reading // caller must hold the media tree write lock // work on DVDs or floppies list? // lock the images lists (list + map) while checking for conflicts tr(
"Cannot register the image '%s' with UUID {%RTuuid} because a %s already exists in the media registry ('%s')"),
// access the list directly because we already locked the list above * Removes the given image from the CD/DVD or floppy image registry. * @param argImage Image object to remove. * @param argType Either DeviceType_DVD or DeviceType_Floppy. * @param pfNeedsSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true * by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed. * @note Caller must hold the media tree lock for writing; in addition, this locks @a argImage for reading // caller must hold the media tree write lock // work on DVDs or floppies list? // access the list directly because the caller must have requested the lock * Creates the path to the specified file according to the path information * present in the file name. * Note that the given file name must contain the full path otherwise the * extracted relative path will be created based on the current working * directory which is normally unknown. * @param aFileName Full file name which path needs to be created. * @return Extended error information on failure to create the path. tr(
"Could not create the directory '%s' (%Rrc)"),
* Handles unexpected exceptions by turning them into COM errors in release * builds or by hitting a breakpoint in the release builds. rc = VirtualBox::handleUnexpectedExceptions (RT_SRC_POS); * @param RT_SRC_POS_DECL "RT_SRC_POS" macro instantiation. /* re-throw the current exception */ /* should not get here */ * Returns the lock handle which protects the media trees (hard disks, * DVDs, floppies). As opposed to version 3.1 and earlier, these lists * are no longer protected by the VirtualBox lock, but by this more * specialized lock. Mind the locking order: always request this lock * after the VirtualBox object lock but before the locks of the media * objects contained in these lists. See AutoLock.h. * Thread function that watches the termination of all client processes * that have opened sessions using IVirtualBox::OpenSession() /// @todo (dmik) processes reaping! /* VirtualBox has been early uninitialized, terminate */ /* release the caller to let uninit() ever proceed */ /* Restore the caller before using VirtualBox. If it fails, this * means VirtualBox is being uninitialized and we must terminate. */ /* update event is signaled */ /* machine mutex is released */ /* machine mutex is abandoned due to client process termination */ /* spawned VM process has terminated (normally or abnormally) */ /* close old process handles */ // lock the machines list for reading /* obtain a new set of opened machines */ /// @todo handle situations with more than 64 objects (
"MAXIMUM_WAIT_OBJECTS reached"));
/* obtain a new set of spawned machines */ /// @todo handle situations with more than 64 objects (
"MAXIMUM_WAIT_OBJECTS reached"));
// machines lock unwinds here /* close old process handles */ /* release sets of machines if any */ /// @todo (dmik) processes reaping! /* according to PMREF, 64 is the maximum for the muxwait list */ /* VirtualBox has been early uninitialized, terminate */ /* release the caller to let uninit() ever proceed */ /* Restore the caller before using VirtualBox. If it fails, this * means VirtualBox is being uninitialized and we must terminate. */ /* update event is signaled */ (
"RTSemEventWait returned %Rrc\n",
vrc));
/* are there any mutexes? */ /* figure out what's going on with machines */ /* machine mutex is normally released */ /* machine mutex is abandoned due to client process * termination; find which mutex is in the Owner Died /* close the dead mutex as asked by PMREF */ (
"DosWaitMuxWaitSem returned %d\n",
arc));
/* are there any spawning sessions? */ /* close the old muxsem */ /* obtain a new set of opened machines */ /// @todo handle situations with more than 64 objects (
"maximum of 64 mutex semaphores reached (%d)",
/* create a new muxsem */ (
"DosCreateMuxWaitSem returned %d\n",
arc));
/* obtain a new set of spawned machines */ /* release sets of machines if any */ /* release the caller to let uninit() ever proceed */ * Restore the caller before using VirtualBox. If it fails, this * means VirtualBox is being uninitialized and we must terminate. /* RT_SUCCESS(rc) means an update event is signaled */ // lock the machines list for reading /* obtain a new set of opened machines */ /* obtain a new set of spawned machines */ // machines lock unwinds here /* reap child processes */ "status=%d, reason=%d\n",
LogFlowFunc ((
"pid %d (%x) was NOT reaped, vrc=%Rrc\n",
/* remove the process if it is not already running */ /* release sets of machines if any */ * Thread function that handles custom events posted using #postEvent(). // create an event queue for the current thread // return the queue to the one who created this thread // signal that we're ready //////////////////////////////////////////////////////////////////////////////// * Takes the current list of registered callbacks of the managed VirtualBox * instance, and calls #handleCallback() for every callback item from the * list, passing the item as an argument. * @note Locks the managed VirtualBox object for reading but leaves the lock * before iterating over callbacks and calling their methods. "the callback event is discarded!\n",
/* We don't need mVirtualBox any more, so release it */ /* Make a copy to release the lock before iterating */ /* We don't need mVirtualBox any more, so release it */ //STDMETHODIMP VirtualBox::CreateDHCPServerForInterface (/*IHostNetworkInterface * aIinterface,*/ IDHCPServer ** aServer) * Remembers the given dhcp server by storing it in the hard disk registry. * @param aDHCPServer Dhcp Server object to remember. * @param aSaveRegistry @c true to save hard disk registry to disk (default). * When @a aSaveRegistry is @c true, this operation may fail because of the * failed #saveSettings() method it calls. In this case, the dhcp server object * will not be remembered. It is therefore the responsibility of the caller to * call this method as the last step of some action that requires registration * in order to make sure that only fully functional dhcp server objects get * @note Locks this object for writing and @a aDHCPServer for reading. * Removes the given hard disk from the hard disk registry. * @param aHardDisk Hard disk object to remove. * @param aSaveRegistry @c true to save hard disk registry to disk (default). * When @a aSaveRegistry is @c true, this operation may fail because of the * failed #saveSettings() method it calls. In this case, the hard disk object * will NOT be removed from the registry when this method returns. It is * therefore the responsibility of the caller to call this method as the first * step of some action that requires unregistration, before calling uninit() on * @note Locks this object for writing and @a aHardDisk for reading. /* vi: set tabstop=4 shiftwidth=4 expandtab: */