Changeset 107866 in vbox for trunk/src/VBox/Main/src-all/ObjectsTracker.cpp
- Timestamp:
- Jan 21, 2025 5:41:50 AM (3 weeks ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-all/ObjectsTracker.cpp
r107260 r107866 25 25 * SPDX-License-Identifier: GPL-3.0-only 26 26 */ 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 */ 27 155 28 156 #define LOG_GROUP LOG_GROUP_MAIN
Note:
See TracChangeset
for help on using the changeset viewer.