- Timestamp:
- Sep 7, 2020 3:37:43 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/MediumImpl.cpp
r85908 r86047 66 66 //////////////////////////////////////////////////////////////////////////////// 67 67 68 struct SnapshotRef 69 { 70 /** Equality predicate for stdc++. */ 71 struct EqualsTo : public std::unary_function <SnapshotRef, bool> 72 { 73 explicit EqualsTo(const Guid &aSnapshotId) : snapshotId(aSnapshotId) {} 74 75 bool operator()(const argument_type &aThat) const 76 { 77 return aThat.snapshotId == snapshotId; 78 } 79 80 const Guid snapshotId; 81 }; 82 83 SnapshotRef(const Guid &aSnapshotId, 84 const int &aRefCnt = 1) 85 : snapshotId(aSnapshotId), 86 iRefCnt(aRefCnt) {} 87 88 Guid snapshotId; 89 /* 90 * The number of attachments of the medium in the same snapshot. 91 * Used for MediumType_Readonly. It is always equal to 1 for other types. 92 * Usual int is used because any changes in the BackRef are guarded by 93 * AutoWriteLock. 94 */ 95 int iRefCnt; 96 }; 97 68 98 /** Describes how a machine refers to this medium. */ 69 99 struct BackRef … … 85 115 const Guid &aSnapshotId = Guid::Empty) 86 116 : machineId(aMachineId), 117 iRefCnt(1), 87 118 fInCurState(aSnapshotId.isZero()) 88 119 { 89 120 if (aSnapshotId.isValid() && !aSnapshotId.isZero()) 90 llSnapshotIds.push_back( aSnapshotId);121 llSnapshotIds.push_back(SnapshotRef(aSnapshotId)); 91 122 } 92 123 93 124 Guid machineId; 125 /* 126 * The number of attachments of the medium in the same machine. 127 * Used for MediumType_Readonly. It is always equal to 1 for other types. 128 * Usual int is used because any changes in the BackRef are guarded by 129 * AutoWriteLock. 130 */ 131 int iRefCnt; 94 132 bool fInCurState : 1; 95 GuidListllSnapshotIds;133 std::list<SnapshotRef> llSnapshotIds; 96 134 }; 97 135 … … 1474 1512 1475 1513 AutoWriteLock treeLock(pVirtualBox->i_getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); 1514 #if DEBUG 1515 if (!m->backRefs.empty()) 1516 i_dumpBackRefs(); 1517 #endif 1518 Assert(m->backRefs.empty()); 1476 1519 1477 1520 /* Enclose the state transition Ready->InUninit->NotReady */ … … 2138 2181 aSnapshotIds[j++] = it->machineId.toUtf16(); 2139 2182 2140 for( GuidList::const_iterator jt = it->llSnapshotIds.begin(); jt != it->llSnapshotIds.end(); ++jt, ++j)2141 aSnapshotIds[j] = (*jt);2183 for(std::list<SnapshotRef>::const_iterator jt = it->llSnapshotIds.begin(); jt != it->llSnapshotIds.end(); ++jt, ++j) 2184 aSnapshotIds[j] = jt->snapshotId; 2142 2185 } 2143 2186 … … 4295 4338 return S_OK; 4296 4339 } 4340 bool fDvd = false; 4341 { 4342 AutoReadLock arlock(this COMMA_LOCKVAL_SRC_POS); 4343 fDvd = m->type == MediumType_Readonly || m->devType == DeviceType_DVD; 4344 } 4297 4345 4298 4346 // if the caller has not supplied a snapshot ID, then we're attaching … … 4303 4351 { 4304 4352 // Allow MediumType_Readonly mediums and DVD in particular to be attached twice. 4305 AutoReadLock arlock(this COMMA_LOCKVAL_SRC_POS); 4306 if (m->type == MediumType_Readonly || m->devType == DeviceType_DVD) 4307 { 4308 BackRef ref(aMachineId, aSnapshotId); 4309 m->backRefs.push_back(ref); 4353 // (the medium already had been added to back reference) 4354 if (fDvd) 4355 { 4356 it->iRefCnt++; 4310 4357 return S_OK; 4311 4358 } … … 4325 4372 // otherwise: a snapshot medium is being attached 4326 4373 4327 /* sanity: no duplicate attachments except MediumType_Readonly (DVD)*/4328 for ( GuidList::const_iterator jt = it->llSnapshotIds.begin();4374 /* sanity: no duplicate attachments */ 4375 for (std::list<SnapshotRef>::iterator jt = it->llSnapshotIds.begin(); 4329 4376 jt != it->llSnapshotIds.end(); 4330 4377 ++jt) 4331 4378 { 4332 const Guid &idOldSnapshot = *jt; 4333 4334 if ( idOldSnapshot == aSnapshotId 4335 && m->type != MediumType_Readonly 4336 && m->devType != DeviceType_DVD 4337 ) 4338 { 4379 const Guid &idOldSnapshot = jt->snapshotId; 4380 4381 if (idOldSnapshot == aSnapshotId) 4382 { 4383 if (fDvd) 4384 { 4385 jt->iRefCnt++; 4386 return S_OK; 4387 } 4339 4388 #ifdef DEBUG 4340 4389 i_dumpBackRefs(); … … 4348 4397 } 4349 4398 4350 it->llSnapshotIds.push_back( aSnapshotId);4399 it->llSnapshotIds.push_back(SnapshotRef(aSnapshotId)); 4351 4400 // Do not touch fInCurState, as the image may be attached to the current 4352 4401 // state *and* a snapshot, otherwise we lose the current state association! … … 4382 4431 if (aSnapshotId.isZero()) 4383 4432 { 4433 it->iRefCnt--; 4434 if (it->iRefCnt > 0) 4435 return S_OK; 4436 4384 4437 /* remove the current state attachment */ 4385 4438 it->fInCurState = false; … … 4388 4441 { 4389 4442 /* remove the snapshot attachment */ 4390 GuidList::iterator jt = std::find(it->llSnapshotIds.begin(), 4391 it->llSnapshotIds.end(), 4392 aSnapshotId); 4443 std::list<SnapshotRef>::iterator jt = 4444 std::find_if(it->llSnapshotIds.begin(), 4445 it->llSnapshotIds.end(), 4446 SnapshotRef::EqualsTo(aSnapshotId)); 4393 4447 4394 4448 AssertReturn(jt != it->llSnapshotIds.end(), E_FAIL); 4449 4450 jt->iRefCnt--; 4451 if (jt->iRefCnt > 0) 4452 return S_OK; 4453 4395 4454 it->llSnapshotIds.erase(jt); 4396 4455 } … … 4451 4510 return NULL; 4452 4511 4453 return &ref.llSnapshotIds.front() ;4512 return &ref.llSnapshotIds.front().snapshotId; 4454 4513 } 4455 4514 … … 4476 4535 { 4477 4536 const BackRef &ref = *it2; 4478 LogFlowThisFunc((" Backref from machine {%RTuuid} (fInCurState: %d )\n", ref.machineId.raw(), ref.fInCurState));4479 4480 for ( GuidList::const_iterator jt2 = it2->llSnapshotIds.begin();4537 LogFlowThisFunc((" Backref from machine {%RTuuid} (fInCurState: %d, iRefCnt: %d)\n", ref.machineId.raw(), ref.fInCurState, ref.iRefCnt)); 4538 4539 for (std::list<SnapshotRef>::const_iterator jt2 = it2->llSnapshotIds.begin(); 4481 4540 jt2 != it2->llSnapshotIds.end(); 4482 4541 ++jt2) 4483 4542 { 4484 const Guid &id = *jt2;4485 LogFlowThisFunc((" Backref from snapshot {%RTuuid} \n", id.raw()));4543 const Guid &id = jt2->snapshotId; 4544 LogFlowThisFunc((" Backref from snapshot {%RTuuid} (iRefCnt = %d)\n", id.raw(), jt2->iRefCnt)); 4486 4545 } 4487 4546 }
Note:
See TracChangeset
for help on using the changeset viewer.