VirtualBox

Ignore:
Timestamp:
Jan 21, 2025 5:41:50 AM (3 weeks ago)
Author:
vboxsync
Message:

bugref:10806. Added documentation as the comment. It contains some description and the examples.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-all/ObjectsTracker.cpp

    r107260 r107866  
    2525 * SPDX-License-Identifier: GPL-3.0-only
    2626 */
     27
     28/*
     29 * Sometimes user wants to check or retrieve data or information about objects that may not exist at the time
     30 * the user requests such objects. For example, some action was completed some time ago and all data related to
     31 * this action was deleted, but the user missed this moment and later still wants to know how the action was
     32 * completed. If it were possible to store such objects for some time, it would help the user.
     33 *
     34 * Example with Progress object
     35 * 1. When Progress object is created it’s added into TrackedObjectCollector (call setTracked() in Progress::FinalConstruct()).
     36 *
     37 * 2. User keeps the Progress Id. VirtualBox API returns Progress Id to user everywhere where its’ needed.
     38 * When user wants to know the status of action he makes a request to VirtualBox calling the function
     39 * VirtualBox::getTrackedObject(). This function looks through TrackedObjectCollector and retrieves the information
     40 * about a requested object and if one exists there returns a pointer to IUnknown interface.
     41 * This pointer should be converted to the appropriate interface type (IProgress in this case). Next the data are
     42 * extracted using the interface functions.
     43 *
     44 * 2.1. Approach 1.
     45 * Getting information about a tracked object using VirtualBox API (VirtualBox frontend or any external client)
     46 *  - Call VirtualBox::getTrackedObjectIds() with a requested interface name and get back the list of tracked objects.
     47 *  - Go through the list, call VirtualBox::getTrackedObject() for each Id from the list.
     48 *  - Convert IUnknown interface to the requested interface.
     49 *  - Retrieve information about an object.
     50 *
     51 *  See the full example 1 below.
     52 *
     53 * 2.2. Approach 2
     54 * Getting information about a tracked object on server side (VBoxSVC) is:
     55 *  - Call TrackedObjectsCollector::getObjIdsByClassIID() with the interface name IID (our case is IID_IProgress)
     56 *    and get back the list of tracked objects.
     57 *  - Go through the list, call TrackedObjectsCollectorState::getObj() for each Id from the list.
     58 *  - Convert IUnknown interface to the requested interface.
     59 *  - Retrieve information about an object.
     60 *
     61 * See the full example 2 below.
     62 *
     63 * 3. Class TrackedObjectData keeps some additional data about the tracked object as creation time, last access time,
     64 * life time and etc.
     65 *
     66 * 4. The last access time is updated for the requested object if it's needed (in the class TrackedObjectData).
     67 *
     68 * 5. For managing the items stored in the TrackedObjectCollector, a new thread TrackedObjectsThread is launched
     69 * in VirtualBox::init() function.
     70 *
     71 * 6. Periodically (1 sec at present), the thread TrackedObjectsThread goes through the list of tracked objects,
     72 * measures the difference between the current time and the creation time, if this value is greater than the life
     73 * time the object is marked as "lifetime expired" and next the idletime is started for this object. When the idle
     74 * time is expired the object is removed from the TrackedObjectsCollector.
     75 *
     76 * 7. There is a special case for an object with lifetime = 0. This means that the object has an infinite lifetime.
     77 * How to handle this case? The idea is that the reference count of an unused object is 1, since the object is only
     78 * represented inside the TrackedObjectCollector. When the count is 1, we mark the lifetime as expired and update
     79 * the object with new data. After this action, the logic becomes standard (see point 6).
     80 *
     81 * Addon.
     82 * Example 1. Getting information about a Progress tracked object on server side (VBoxSVC)
     83 *
     84 *  std::vector<com::Utf8Str> lObjIdMap;
     85 *  gTrackedObjectsCollector.getObjIdsByClassIID(IID_IProgress, lObjIdMap);
     86 *  for (const com::Utf8Str &item : lObjIdMap)
     87 *  {
     88 *      if (gTrackedObjectsCollector.checkObj(item.c_str()))
     89 *      {
     90 *          TrackedObjectData temp;
     91 *          gTrackedObjectsCollector.getObj(item.c_str(), temp);
     92 *          Log2(("Tracked Progress Object with objectId %s was found\n", temp.objectIdStr().c_str()));
     93 *
     94 *          ComPtr<IProgress> pProgress;
     95 *          temp.getInterface()->QueryInterface(IID_IProgress, (void **)pProgress.asOutParam());
     96 *          if (pProgress.isNotNull())
     97 *          {
     98 *              com::Bstr reqId(aId.toString());
     99 *              Bstr foundId;
     100 *              pProgress->COMGETTER(Id)(foundId.asOutParam());
     101 *              if (reqId == foundId)
     102 *              {
     103 *                  BOOL aCompleted;
     104 *                  pProgress->COMGETTER(Completed)(&aCompleted);
     105 *
     106 *                  BOOL aCanceled;
     107 *                  pProgress->COMGETTER(Canceled)(&aCanceled);
     108 *
     109 *                  aProgressObject = pProgress;
     110 *                  return S_OK;
     111 *              }
     112 *          }
     113 *      }
     114 *  }
     115 *
     116 * Example 2. Getting information about a Progress tracked object using VirtualBox API
     117 *
     118 *  Utf8Str strObjUuid; // passed from the client
     119 *  Utf8Str strIfaceName;// passed from the client
     120 *  ComPtr<IVirtualBox> pVirtualBox;// set before. Usually each client has own ComPtr<IVirtualBox>.
     121 *
     122 *  com::SafeArray<BSTR> ObjIDsList;
     123 *  hrc = pVirtualBox->GetTrackedObjectIds(Bstr(strIfaceName).raw(), ComSafeArrayAsOutParam(ObjIDsList));
     124 *  if (SUCCEEDED(hrc))
     125 *  {
     126 *      map < Bstr, TrackedObjInfo_T > lObjInfoMap;
     127 *      for (size_t i = 0; i < ObjIDsList.size(); ++i)
     128 *      {
     129 *          Bstr bstrObjId = ObjIDsList[i];
     130 *          if (bstrObjId.equals(strObjUuid.c_str()))
     131 *          {
     132 *              TrackedObjInfo_T objInfo;
     133 *              hrc = pVirtualBox->GetTrackedObject(bstrObjId.raw(),
     134 *                                                  objInfo.pIUnknown.asOutParam(),
     135 *                                                  &objInfo.enmState,
     136 *                                                  &objInfo.creationTime,
     137 *                                                  &objInfo.deletionTime);
     138 *
     139 *              // print tracked object information as state, creation time, deletion time
     140 *              // objInfo.enmState, objInfo.creationTime, objInfo.deletionTime
     141 *
     142 *              if (objInfo.enmState != TrackedObjectState_Invalid)
     143 *              {
     144 *                  // Conversion IUnknown -> IProgress
     145 *                  ComPtr<IProgress> pObj;
     146 *                  objInfo.pIUnknown->QueryInterface(IID_IProgress, (void **)pObj.asOutParam());
     147 *                  if (pObj.isNotNull())
     148 *                      //print Progress Object data as description, completion, cancellation etc.
     149 *              }
     150 *              break;
     151 *          }
     152 *      }
     153 *  }
     154*/
    27155
    28156#define LOG_GROUP LOG_GROUP_MAIN
Note: See TracChangeset for help on using the changeset viewer.

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