- Timestamp:
- Mar 26, 2009 11:27:20 AM (16 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/ApplianceImpl.cpp
r18301 r18304 1711 1711 try 1712 1712 { 1713 if (!task->progress.isNull())1714 task->progress->setNextOperation(BstrFmt(tr("Importing virtual system %d"), i + 1),1715 pAppliance->m->ulWeightPerOperation);1716 1717 1713 /* Guest OS type */ 1718 1714 std::list<VirtualSystemDescriptionEntry*> vsdeOS; … … 2138 2134 } 2139 2135 2140 // now loop until the asynchronous operation completes and then report its result 2141 BOOL fCompleted; 2142 BOOL fCanceled; 2143 ULONG currentPercent; 2144 while (SUCCEEDED(pProgress2->COMGETTER(Completed(&fCompleted)))) 2145 { 2146 rc = task->progress->COMGETTER(Canceled)(&fCanceled); 2147 if (FAILED(rc)) throw rc; 2148 if (fCanceled) 2149 { 2150 pProgress2->Cancel(); 2151 break; 2152 } 2153 else 2154 { 2155 rc = pProgress2->COMGETTER(Percent(¤tPercent)); 2156 if (FAILED(rc)) throw rc; 2157 if (!task->progress.isNull()) 2158 task->progress->setCurrentOperationProgress(currentPercent); 2159 if (fCompleted) 2160 break; 2161 } 2162 /* Make sure the loop is not too tight */ 2163 rc = pProgress2->WaitForCompletion(100); 2164 if (FAILED(rc)) throw rc; 2165 } 2166 // report result of asynchronous operation 2167 HRESULT vrc; 2168 rc = pProgress2->COMGETTER(ResultCode)(&vrc); 2169 if (FAILED(rc)) throw rc; 2170 2171 // if the thread of the progress object has an error, then 2172 // retrieve the error info from there, or it'll be lost 2173 if (FAILED(vrc)) 2174 { 2175 ProgressErrorInfo info(pProgress2); 2176 Utf8Str str(info.getText()); 2177 const char *pcsz = str.c_str(); 2178 HRESULT rc2 = setError(vrc, 2179 pcsz); 2180 throw rc2; 2181 } 2136 // now wait for the background disk operation to complete; this throws HRESULTs on error 2137 pAppliance->waitForAsyncProgress(task->progress, pProgress2); 2182 2138 2183 2139 if (fSourceHdNeedsClosing) … … 3032 2988 pDiskEntry->ulSizeMB); // operation's weight, as set up with the IProgress originally); 3033 2989 3034 // now loop until the asynchronous operation completes and then report its result 3035 BOOL fCompleted; 3036 BOOL fCanceled; 3037 ULONG currentPercent; 3038 while (SUCCEEDED(pProgress2->COMGETTER(Completed(&fCompleted)))) 3039 { 3040 rc = task->progress->COMGETTER(Canceled)(&fCanceled); 3041 if (FAILED(rc)) throw rc; 3042 if (fCanceled) 3043 { 3044 pProgress2->Cancel(); 3045 break; 3046 } 3047 else 3048 { 3049 rc = pProgress2->COMGETTER(Percent(¤tPercent)); 3050 if (FAILED(rc)) throw rc; 3051 if (!task->progress.isNull()) 3052 task->progress->setCurrentOperationProgress(currentPercent); 3053 if (fCompleted) 3054 break; 3055 } 3056 /* Make sure the loop is not too tight */ 3057 rc = pProgress2->WaitForCompletion(100); 3058 if (FAILED(rc)) throw rc; 3059 } 3060 // report result of asynchronous operation 3061 HRESULT vrc; 3062 rc = pProgress2->COMGETTER(ResultCode)(&vrc); 3063 if (FAILED(rc)) throw rc; 3064 3065 // if the thread of the progress object has an error, then 3066 // retrieve the error info from there, or it'll be lost 3067 if (FAILED(vrc)) 3068 { 3069 ProgressErrorInfo info(pProgress2); 3070 Utf8Str str(info.getText()); 3071 const char *pcsz = str.c_str(); 3072 HRESULT rc2 = setError(vrc, pcsz); 3073 throw rc2; 3074 } 2990 // now wait for the background disk operation to complete; this throws HRESULTs on error 2991 pAppliance->waitForAsyncProgress(task->progress, pProgress2); 3075 2992 } 3076 2993 catch (HRESULT rc3) 3077 2994 { 3078 // upon error after register eing, close the disk or2995 // upon error after registering, close the disk or 3079 2996 // it'll stick in the registry forever 3080 2997 pTargetDisk->Close(); … … 3230 3147 pProgress.createObject(); 3231 3148 3232 // use one percent for parsing the XML and one percent for each virtual system3233 // in the XML; use the rest (e.g. 97%) for the disk images3234 ULONG cFixed = 1 + m->virtualSystemDescriptions.size();3235 ULONG ulPercentForDisks = 100 - cFixed;3236 3237 3149 // weigh the disk images according to their sizes 3238 3150 uint32_t ulTotalMB = 0; … … 3256 3168 } 3257 3169 3170 ULONG cOperations = 1 + cDisks; // one op per disk plus 1 for the XML 3171 3258 3172 ULONG ulTotalOperationsWeight; 3259 3173 if (ulTotalMB) 3260 3174 { 3261 ulTotalOperationsWeight = ulTotalMB * 100 / ulPercentForDisks;3262 m->ulWeightPerOperation = ulTotalOperationsWeight / 100;3175 ulTotalOperationsWeight = (ULONG)((double)ulTotalMB * 99 / 100); // use 99% of the progress for the disks 3176 m->ulWeightPerOperation = (ULONG)((double)ulTotalMB * 1 / 100); // use 1% of the progress for the XML 3263 3177 } 3264 3178 else 3265 3179 { 3266 3180 // no disks to export: 3267 ulTotalOperationsWeight = cFixed;3181 ulTotalOperationsWeight = 1; 3268 3182 m->ulWeightPerOperation = 1; 3269 3183 } 3270 3184 3271 Log(("Setting up progress object: ulTotalMB = %d, c Fixed = %d, cDisks = %d, => cOperations = %d, ulTotalOperationsWeight = %d, m->ulWeightPerOperation = %d\n",3272 ulTotalMB, c Fixed, cDisks, cFixed + (ULONG)cDisks, ulTotalOperationsWeight, m->ulWeightPerOperation));3185 Log(("Setting up progress object: ulTotalMB = %d, cDisks = %d, => cOperations = %d, ulTotalOperationsWeight = %d, m->ulWeightPerOperation = %d\n", 3186 ulTotalMB, cDisks, cOperations, ulTotalOperationsWeight, m->ulWeightPerOperation)); 3273 3187 3274 3188 rc = pProgress->init(mVirtualBox, static_cast<IAppliance*>(this), 3275 3189 bstrDescription, 3276 3190 TRUE /* aCancelable */, 3277 c Fixed + (ULONG)cDisks, // ULONG cOperations,3191 cOperations, // ULONG cOperations, 3278 3192 ulTotalOperationsWeight, // ULONG ulTotalOperationsWeight, 3279 3193 bstrDescription, // CBSTR bstrFirstOperationDescription, 3280 3194 m->ulWeightPerOperation); // ULONG ulFirstOperationWeight, 3281 3195 return rc; 3196 } 3197 3198 /** 3199 * Called from the import and export background threads to synchronize the second 3200 * background disk thread's progress object with the current progress object so 3201 * that the user interface sees progress correctly and that cancel signals are 3202 * passed on to the second thread. 3203 * @param pProgressThis Progress object of the current thread. 3204 * @param pProgressAsync Progress object of asynchronous task running in background. 3205 */ 3206 void Appliance::waitForAsyncProgress(ComObjPtr<Progress> &pProgressThis, 3207 ComPtr<IProgress> &pProgressAsync) 3208 { 3209 HRESULT rc; 3210 3211 // now loop until the asynchronous operation completes and then report its result 3212 BOOL fCompleted; 3213 BOOL fCanceled; 3214 ULONG currentPercent; 3215 while (SUCCEEDED(pProgressAsync->COMGETTER(Completed(&fCompleted)))) 3216 { 3217 rc = pProgressThis->COMGETTER(Canceled)(&fCanceled); 3218 if (FAILED(rc)) throw rc; 3219 if (fCanceled) 3220 { 3221 pProgressAsync->Cancel(); 3222 break; 3223 } 3224 3225 rc = pProgressAsync->COMGETTER(Percent(¤tPercent)); 3226 if (FAILED(rc)) throw rc; 3227 if (!pProgressThis.isNull()) 3228 pProgressThis->setCurrentOperationProgress(currentPercent); 3229 if (fCompleted) 3230 break; 3231 3232 /* Make sure the loop is not too tight */ 3233 rc = pProgressAsync->WaitForCompletion(100); 3234 if (FAILED(rc)) throw rc; 3235 } 3236 // report result of asynchronous operation 3237 HRESULT vrc; 3238 rc = pProgressAsync->COMGETTER(ResultCode)(&vrc); 3239 if (FAILED(rc)) throw rc; 3240 3241 3242 // if the thread of the progress object has an error, then 3243 // retrieve the error info from there, or it'll be lost 3244 if (FAILED(vrc)) 3245 { 3246 ProgressErrorInfo info(pProgressAsync); 3247 Utf8Str str(info.getText()); 3248 const char *pcsz = str.c_str(); 3249 HRESULT rc2 = setError(vrc, pcsz); 3250 throw rc2; 3251 } 3282 3252 } 3283 3253 -
trunk/src/VBox/Main/include/ApplianceImpl.h
r18269 r18304 98 98 HRESULT searchUniqueDiskImageFilePath(Utf8Str& aName) const; 99 99 HRESULT setUpProgress(ComObjPtr<Progress> &pProgress, const Bstr &bstrDescription); 100 void waitForAsyncProgress(ComObjPtr<Progress> &pProgressThis, ComPtr<IProgress> &pProgressAsync); 100 101 void addWarning(const char* aWarning, ...); 101 102
Note:
See TracChangeset
for help on using the changeset viewer.