MediaManager.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00012 #include <map>
00013 #include <list>
00014 #include <iostream>
00015 #include <typeinfo>
00016
00017 #include "zypp/media/MediaException.h"
00018 #include "zypp/media/MediaManager.h"
00019 #include "zypp/media/MediaHandler.h"
00020 #include "zypp/media/Mount.h"
00021 #include "zypp/thread/Mutex.h"
00022 #include "zypp/thread/MutexLock.h"
00023
00024 #include "zypp/base/String.h"
00025 #include "zypp/base/Logger.h"
00026 #include "zypp/Pathname.h"
00027 #include "zypp/PathInfo.h"
00028
00030 namespace zypp
00031 {
00032
00034 namespace media
00035 {
00036
00037 using zypp::thread::Mutex;
00038 using zypp::thread::MutexLock;
00039
00041 namespace
00042 {
00043
00044
00045
00046
00047 static Mutex g_Mutex;
00048
00049
00050
00051 struct ManagedMedia
00052 {
00053 ~ManagedMedia()
00054 {}
00055
00056 ManagedMedia()
00057 : desired (false)
00058 {}
00059
00060 ManagedMedia(const ManagedMedia &m)
00061 : desired (m.desired)
00062 , handler (m.handler)
00063 , verifier(m.verifier)
00064 {}
00065
00066 ManagedMedia(const MediaAccessRef &h, const MediaVerifierRef &v)
00067 : desired (false)
00068 , handler (h)
00069 , verifier(v)
00070 {}
00071
00072 inline void
00073 checkAttached(MediaAccessId id)
00074 {
00075 if( !handler->isAttached())
00076 {
00077 DBG << "checkAttached(" << id << ") not attached" << std::endl;
00078 desired = false;
00079 ZYPP_THROW(MediaNotAttachedException(
00080 handler->url()
00081 ));
00082 }
00083 }
00084
00085 inline void
00086 checkDesired(MediaAccessId id)
00087 {
00088 checkAttached(id);
00089
00090 if( !desired)
00091 {
00092 try {
00093 desired = verifier->isDesiredMedia(handler);
00094 }
00095 catch(const zypp::Exception &e) {
00096 ZYPP_CAUGHT(e);
00097 desired = false;
00098 }
00099
00100 if( !desired)
00101 {
00102 DBG << "checkDesired(" << id << "): not desired (report by "
00103 << verifier->info() << ")" << std::endl;
00104 ZYPP_THROW(MediaNotDesiredException(
00105 handler->url()
00106 ));
00107 }
00108
00109 DBG << "checkDesired(" << id << "): desired (report by "
00110 << verifier->info() << ")" << std::endl;
00111 } else {
00112 DBG << "checkDesired(" << id << "): desired (cached)" << std::endl;
00113 }
00114 }
00115
00116 bool desired;
00117 MediaAccessRef handler;
00118 MediaVerifierRef verifier;
00119 };
00120
00121
00122
00123 typedef std::map<MediaAccessId, ManagedMedia> ManagedMediaMap;
00124
00126 }
00128
00129
00131 std::string
00132 MediaVerifierBase::info() const
00133 {
00134 return std::string(typeid((*this)).name());
00135 }
00136
00137
00139 std::string
00140 NoVerifier::info() const
00141 {
00142 return std::string("zypp::media::NoVerifier");
00143 }
00144
00145
00147 class MediaManager_Impl
00148 {
00149 private:
00150 friend class MediaManager;
00151
00152 MediaAccessId last_accessid;
00153 ManagedMediaMap mediaMap;
00154
00155 MediaManager_Impl()
00156 : last_accessid(0)
00157 {}
00158
00159 public:
00160 ~MediaManager_Impl()
00161 {
00162 MutexLock glock(g_Mutex);
00163
00164 try
00165 {
00166
00167 ManagedMediaMap::iterator it;
00168 bool found;
00169 do
00170 {
00171 found = false;
00172 for(it = mediaMap.begin(); it != mediaMap.end(); )
00173 {
00174 if( it->second.handler->dependsOnParent())
00175 {
00176 found = true;
00177
00178
00179 it->second.handler->resetParentId();
00180 mediaMap.erase( it++ );
00181 } else {
00182 ++it;
00183 }
00184 }
00185 } while(found);
00186
00187
00188 mediaMap.clear();
00189 }
00190 catch( ... )
00191 {}
00192 }
00193
00194 inline MediaAccessId
00195 nextAccessId()
00196 {
00197 return ++last_accessid;
00198 }
00199
00200 inline bool
00201 hasId(MediaAccessId accessId) const
00202 {
00203 return mediaMap.find(accessId) != mediaMap.end();
00204 }
00205
00206 inline ManagedMedia &
00207 findMM(MediaAccessId accessId)
00208 {
00209 ManagedMediaMap::iterator it( mediaMap.find(accessId));
00210 if( it == mediaMap.end())
00211 {
00212 ZYPP_THROW(MediaNotOpenException(
00213 "Invalid media access id " + str::numstring(accessId)
00214 ));
00215 }
00216 return it->second;
00217 }
00218
00219 static inline time_t
00220 getMountTableMTime()
00221 {
00222 time_t mtime = zypp::PathInfo("/etc/mtab").mtime();
00223 if( mtime <= 0)
00224 {
00225 WAR << "Failed to retrieve modification time of '/etc/mtab'"
00226 << std::endl;
00227 }
00228 return mtime;
00229 }
00230
00231 static inline MountEntries
00232 getMountEntries()
00233 {
00234
00235
00236 return Mount::getEntries();
00237 }
00238
00239 };
00240
00241
00243
00244 zypp::RW_pointer<MediaManager_Impl> MediaManager::m_impl(NULL);
00245
00246
00248 MediaManager::MediaManager()
00249 {
00250 MutexLock glock(g_Mutex);
00251 if( !m_impl)
00252 {
00253 m_impl.reset( new MediaManager_Impl());
00254 }
00255 }
00256
00257
00258 MediaManager::~MediaManager()
00259 {
00260 }
00261
00262
00263 MediaAccessId
00264 MediaManager::open(const Url &url, const Pathname &preferred_attach_point)
00265 {
00266 MutexLock glock(g_Mutex);
00267
00268
00269 MediaAccessRef handler( new MediaAccess());
00270 MediaVerifierRef verifier( new NoVerifier());
00271 ManagedMedia tmp( handler, verifier);
00272
00273 tmp.handler->open(url, preferred_attach_point);
00274
00275 MediaAccessId nextId = m_impl->nextAccessId();
00276
00277 m_impl->mediaMap[nextId] = tmp;
00278
00279 DBG << "Opened new media access using id " << nextId
00280 << " to " << url.asString() << std::endl;
00281 return nextId;
00282 }
00283
00284
00285 void
00286 MediaManager::close(MediaAccessId accessId)
00287 {
00288 MutexLock glock(g_Mutex);
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00301 for( ; m != m_impl->mediaMap.end(); ++m)
00302 {
00303 if( m->second.handler->dependsOnParent(accessId, true))
00304 {
00305 ZYPP_THROW(MediaIsSharedException(
00306 m->second.handler->url().asString()
00307 ));
00308 }
00309 }
00310
00311 DBG << "Close to access handler using id "
00312 << accessId << " requested" << std::endl;
00313
00314 ManagedMedia &ref( m_impl->findMM(accessId));
00315 ref.handler->close();
00316
00317 m_impl->mediaMap.erase(accessId);
00318 }
00319
00320
00321 bool
00322 MediaManager::isOpen(MediaAccessId accessId) const
00323 {
00324 MutexLock glock(g_Mutex);
00325
00326 ManagedMediaMap::iterator it( m_impl->mediaMap.find(accessId));
00327 return it != m_impl->mediaMap.end() &&
00328 it->second.handler->isOpen();
00329 }
00330
00331
00332 std::string
00333 MediaManager::protocol(MediaAccessId accessId) const
00334 {
00335 MutexLock glock(g_Mutex);
00336
00337 ManagedMedia &ref( m_impl->findMM(accessId));
00338
00339 return ref.handler->protocol();
00340 }
00341
00342
00343 bool
00344 MediaManager::downloads(MediaAccessId accessId) const
00345 {
00346 MutexLock glock(g_Mutex);
00347
00348 ManagedMedia &ref( m_impl->findMM(accessId));
00349
00350 return ref.handler->downloads();
00351 }
00352
00353
00354 Url
00355 MediaManager::url(MediaAccessId accessId) const
00356 {
00357 MutexLock glock(g_Mutex);
00358
00359 ManagedMedia &ref( m_impl->findMM(accessId));
00360
00361 return ref.handler->url();
00362 }
00363
00364
00365 void
00366 MediaManager::addVerifier(MediaAccessId accessId,
00367 const MediaVerifierRef &verifier)
00368 {
00369 MutexLock glock(g_Mutex);
00370
00371 if( !verifier)
00372 ZYPP_THROW(MediaException("Invalid verifier reference"));
00373
00374 ManagedMedia &ref( m_impl->findMM(accessId));
00375
00376 ref.desired = false;
00377 MediaVerifierRef(verifier).swap(ref.verifier);
00378
00379 DBG << "MediaVerifier change: id=" << accessId << ", verifier="
00380 << verifier->info() << std::endl;
00381 }
00382
00383
00384 void
00385 MediaManager::delVerifier(MediaAccessId accessId)
00386 {
00387 MutexLock glock(g_Mutex);
00388
00389 ManagedMedia &ref( m_impl->findMM(accessId));
00390
00391 MediaVerifierRef verifier( new NoVerifier());
00392 ref.desired = false;
00393 ref.verifier.swap(verifier);
00394
00395 DBG << "MediaVerifier change: id=" << accessId << ", verifier="
00396 << verifier->info() << std::endl;
00397 }
00398
00399
00400 bool
00401 MediaManager::setAttachPrefix(const Pathname &attach_prefix)
00402 {
00403 MutexLock glock(g_Mutex);
00404
00405 return MediaHandler::setAttachPrefix(attach_prefix);
00406 }
00407
00408
00409 void MediaManager::attach(MediaAccessId accessId)
00410 {
00411 MutexLock glock(g_Mutex);
00412
00413 ManagedMedia &ref( m_impl->findMM(accessId));
00414
00415 DBG << "attach(id=" << accessId << ")" << std::endl;
00416
00417
00418 ref.handler->attach(false);
00419 try
00420 {
00421 ref.checkDesired(accessId);
00422 return;
00423 }
00424 catch (const MediaException & ex)
00425 {
00426 ZYPP_CAUGHT(ex);
00427
00428 if (!ref.handler->hasMoreDevices())
00429 ZYPP_RETHROW(ex);
00430
00431 if (ref.handler->isAttached())
00432 ref.handler->release();
00433 }
00434
00435 MIL << "checkDesired(" << accessId << ") of first device failed,"
00436 " going to try others with attach(true)" << std::endl;
00437
00438 while (ref.handler->hasMoreDevices())
00439 {
00440 try
00441 {
00442
00443 ref.handler->attach(true);
00444 ref.checkDesired(accessId);
00445 return;
00446 }
00447 catch (const MediaNotDesiredException & ex)
00448 {
00449 ZYPP_CAUGHT(ex);
00450
00451 if (!ref.handler->hasMoreDevices())
00452 {
00453 MIL << "No desired media found after trying all detected devices." << std::endl;
00454 ZYPP_RETHROW(ex);
00455 }
00456
00457 AttachedMedia media(ref.handler->attachedMedia());
00458 DBG << "Skipping " << media.mediaSource->asString() << ": not desired media." << std::endl;
00459
00460 ref.handler->release();
00461 }
00462 catch (const MediaException & ex)
00463 {
00464 ZYPP_CAUGHT(ex);
00465
00466 if (!ref.handler->hasMoreDevices())
00467 ZYPP_RETHROW(ex);
00468
00469 AttachedMedia media(ref.handler->attachedMedia());
00470 DBG << "Skipping " << media.mediaSource->asString() << " because of exception thrown by attach(true)" << std::endl;
00471
00472 if (ref.handler->isAttached()) ref.handler->release();
00473 }
00474 }
00475 }
00476
00477
00478 void
00479 MediaManager::release(MediaAccessId accessId, const std::string & ejectDev)
00480 {
00481 MutexLock glock(g_Mutex);
00482
00483 ManagedMedia &ref( m_impl->findMM(accessId));
00484
00485 DBG << "release(id=" << accessId;
00486 if (!ejectDev.empty())
00487 DBG << ", " << ejectDev;
00488 DBG << ")" << std::endl;
00489
00490 if(!ejectDev.empty())
00491 {
00492
00493
00494
00495
00496
00497
00498 ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00499 for( ; m != m_impl->mediaMap.end(); ++m)
00500 {
00501 if( m->second.handler->dependsOnParent(accessId, false))
00502 {
00503 try
00504 {
00505 DBG << "Forcing release of handler depending on access id "
00506 << accessId << std::endl;
00507 m->second.desired = false;
00508 m->second.handler->release();
00509 }
00510 catch(const MediaException &e)
00511 {
00512 ZYPP_CAUGHT(e);
00513 }
00514 }
00515 }
00516 }
00517 ref.desired = false;
00518 ref.handler->release(ejectDev);
00519 }
00520
00521
00522 void
00523 MediaManager::releaseAll()
00524 {
00525 MutexLock glock(g_Mutex);
00526
00527 MIL << "Releasing all attached media" << std::endl;
00528
00529 ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00530 for( ; m != m_impl->mediaMap.end(); ++m)
00531 {
00532 if( m->second.handler->dependsOnParent())
00533 continue;
00534
00535 try
00536 {
00537 if(m->second.handler->isAttached())
00538 {
00539 DBG << "Releasing media id " << m->first << std::endl;
00540 m->second.desired = false;
00541 m->second.handler->release();
00542 }
00543 else
00544 {
00545 DBG << "Media id " << m->first << " not attached " << std::endl;
00546 }
00547 }
00548 catch(const MediaException & e)
00549 {
00550 ZYPP_CAUGHT(e);
00551 ERR << "Failed to release media id " << m->first << std::endl;
00552 }
00553 }
00554
00555 MIL << "Exit" << std::endl;
00556 }
00557
00558
00559 void
00560 MediaManager::disconnect(MediaAccessId accessId)
00561 {
00562 MutexLock glock(g_Mutex);
00563
00564 ManagedMedia &ref( m_impl->findMM(accessId));
00565
00566 ref.handler->disconnect();
00567 }
00568
00569
00570 bool
00571 MediaManager::isAttached(MediaAccessId accessId) const
00572 {
00573 MutexLock glock(g_Mutex);
00574
00575 ManagedMedia &ref( m_impl->findMM(accessId));
00576
00577 return ref.handler->isAttached();
00578 }
00579
00580
00581 bool MediaManager::isSharedMedia(MediaAccessId accessId) const
00582 {
00583 MutexLock glock(g_Mutex);
00584
00585 ManagedMedia &ref( m_impl->findMM(accessId));
00586
00587 return ref.handler->isSharedMedia();
00588 }
00589
00590
00591 bool
00592 MediaManager::isDesiredMedia(MediaAccessId accessId) const
00593 {
00594 MutexLock glock(g_Mutex);
00595
00596 ManagedMedia &ref( m_impl->findMM(accessId));
00597
00598 if( !ref.handler->isAttached())
00599 {
00600 ref.desired = false;
00601 }
00602 else
00603 {
00604 try {
00605 ref.desired = ref.verifier->isDesiredMedia(ref.handler);
00606 }
00607 catch(const zypp::Exception &e) {
00608 ZYPP_CAUGHT(e);
00609 ref.desired = false;
00610 }
00611 }
00612 DBG << "isDesiredMedia(" << accessId << "): "
00613 << (ref.desired ? "" : "not ")
00614 << "desired (report by "
00615 << ref.verifier->info() << ")" << std::endl;
00616 return ref.desired;
00617 }
00618
00619
00620 bool
00621 MediaManager::isDesiredMedia(MediaAccessId accessId,
00622 const MediaVerifierRef &verifier) const
00623 {
00624 MutexLock glock(g_Mutex);
00625
00626 MediaVerifierRef v(verifier);
00627 if( !v)
00628 ZYPP_THROW(MediaException("Invalid verifier reference"));
00629
00630 ManagedMedia &ref( m_impl->findMM(accessId));
00631
00632 bool desired = false;
00633 if( ref.handler->isAttached())
00634 {
00635 try {
00636 desired = v->isDesiredMedia(ref.handler);
00637 }
00638 catch(const zypp::Exception &e) {
00639 ZYPP_CAUGHT(e);
00640 desired = false;
00641 }
00642 }
00643 DBG << "isDesiredMedia(" << accessId << "): "
00644 << (desired ? "" : "not ")
00645 << "desired (report by "
00646 << v->info() << ")" << std::endl;
00647 return desired;
00648 }
00649
00650
00651 bool
00652 MediaManager::isChangeable(MediaAccessId accessId)
00653 {
00654 return url(accessId).getScheme() == "cd" || url(accessId).getScheme() == "dvd";
00655 }
00656
00657
00658 Pathname
00659 MediaManager::localRoot(MediaAccessId accessId) const
00660 {
00661 MutexLock glock(g_Mutex);
00662
00663 ManagedMedia &ref( m_impl->findMM(accessId));
00664
00665 Pathname path;
00666 path = ref.handler->localRoot();
00667 return path;
00668 }
00669
00670
00671 Pathname
00672 MediaManager::localPath(MediaAccessId accessId,
00673 const Pathname & pathname) const
00674 {
00675 MutexLock glock(g_Mutex);
00676
00677 ManagedMedia &ref( m_impl->findMM(accessId));
00678
00679 Pathname path;
00680 path = ref.handler->localPath(pathname);
00681 return path;
00682 }
00683
00684
00685 void
00686 MediaManager::provideFile(MediaAccessId accessId,
00687 const Pathname &filename ) const
00688 {
00689 MutexLock glock(g_Mutex);
00690
00691 ManagedMedia &ref( m_impl->findMM(accessId));
00692
00693 ref.checkDesired(accessId);
00694
00695 ref.handler->provideFile(filename);
00696 }
00697
00698
00699 void
00700 MediaManager::provideDir(MediaAccessId accessId,
00701 const Pathname &dirname) const
00702 {
00703 MutexLock glock(g_Mutex);
00704
00705 ManagedMedia &ref( m_impl->findMM(accessId));
00706
00707 ref.checkDesired(accessId);
00708
00709 ref.handler->provideDir(dirname);
00710 }
00711
00712
00713 void
00714 MediaManager::provideDirTree(MediaAccessId accessId,
00715 const Pathname &dirname) const
00716 {
00717 MutexLock glock(g_Mutex);
00718
00719 ManagedMedia &ref( m_impl->findMM(accessId));
00720
00721 ref.checkDesired(accessId);
00722
00723 ref.handler->provideDirTree(dirname);
00724 }
00725
00726
00727 void
00728 MediaManager::releaseFile(MediaAccessId accessId,
00729 const Pathname &filename) const
00730 {
00731 MutexLock glock(g_Mutex);
00732
00733 ManagedMedia &ref( m_impl->findMM(accessId));
00734
00735 ref.checkAttached(accessId);
00736
00737 ref.handler->releaseFile(filename);
00738 }
00739
00740
00741 void
00742 MediaManager::releaseDir(MediaAccessId accessId,
00743 const Pathname &dirname) const
00744 {
00745 MutexLock glock(g_Mutex);
00746
00747 ManagedMedia &ref( m_impl->findMM(accessId));
00748
00749 ref.checkAttached(accessId);
00750
00751 ref.handler->releaseDir(dirname);
00752 }
00753
00754
00755
00756 void
00757 MediaManager::releasePath(MediaAccessId accessId,
00758 const Pathname &pathname) const
00759 {
00760 MutexLock glock(g_Mutex);
00761
00762 ManagedMedia &ref( m_impl->findMM(accessId));
00763
00764 ref.checkAttached(accessId);
00765
00766 ref.handler->releasePath(pathname);
00767 }
00768
00769
00770 void
00771 MediaManager::dirInfo(MediaAccessId accessId,
00772 std::list<std::string> &retlist,
00773 const Pathname &dirname,
00774 bool dots) const
00775 {
00776 MutexLock glock(g_Mutex);
00777
00778 ManagedMedia &ref( m_impl->findMM(accessId));
00779
00780
00781 ref.checkAttached(accessId);
00782
00783 ref.handler->dirInfo(retlist, dirname, dots);
00784 }
00785
00786
00787 void
00788 MediaManager::dirInfo(MediaAccessId accessId,
00789 filesystem::DirContent &retlist,
00790 const Pathname &dirname,
00791 bool dots) const
00792 {
00793 MutexLock glock(g_Mutex);
00794
00795 ManagedMedia &ref( m_impl->findMM(accessId));
00796
00797
00798 ref.checkAttached(accessId);
00799
00800 ref.handler->dirInfo(retlist, dirname, dots);
00801 }
00802
00803
00804 bool
00805 MediaManager::doesFileExist(MediaAccessId accessId, const Pathname & filename ) const
00806 {
00807 MutexLock glock(g_Mutex);
00808 ManagedMedia &ref( m_impl->findMM(accessId));
00809
00810
00811 ref.checkAttached(accessId);
00812
00813 return ref.handler->doesFileExist(filename);
00814 }
00815
00816
00817 void
00818 MediaManager::getDetectedDevices(MediaAccessId accessId,
00819 std::vector<std::string> & devices,
00820 unsigned int & index) const
00821 {
00822 MutexLock glock(g_Mutex);
00823 ManagedMedia &ref( m_impl->findMM(accessId));
00824 return ref.handler->getDetectedDevices(devices, index);
00825 }
00826
00827
00828
00829 time_t
00830 MediaManager::getMountTableMTime()
00831 {
00832 MutexLock glock(g_Mutex);
00833 return MediaManager_Impl::getMountTableMTime();
00834 }
00835
00836
00837
00838 MountEntries
00839 MediaManager::getMountEntries()
00840 {
00841 MutexLock glock(g_Mutex);
00842
00843 return MediaManager_Impl::getMountEntries();
00844 }
00845
00846
00847 bool
00848 MediaManager::isUseableAttachPoint(const Pathname &path,
00849 bool mtab) const
00850 {
00851 if( path.empty() || path == "/" || !PathInfo(path).isDir())
00852 return false;
00853
00854 MutexLock glock(g_Mutex);
00855
00856
00857
00858
00859 ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
00860 for( ; m != m_impl->mediaMap.end(); ++m)
00861 {
00862 AttachedMedia ret = m->second.handler->attachedMedia();
00863 if( ret.mediaSource && ret.attachPoint)
00864 {
00865 std::string mnt(ret.attachPoint->path.asString());
00866 std::string our(path.asString());
00867
00868 if( our == mnt)
00869 {
00870
00871 return false;
00872 }
00873 else
00874 if( mnt.size() > our.size() &&
00875 mnt.at(our.size()) == '/' &&
00876 !mnt.compare(0, our.size(), our))
00877 {
00878
00879
00880 return false;
00881 }
00882 }
00883 }
00884
00885 if( !mtab)
00886 return true;
00887
00888
00889
00890
00891 MountEntries entries( m_impl->getMountEntries());
00892 MountEntries::const_iterator e;
00893 for( e = entries.begin(); e != entries.end(); ++e)
00894 {
00895 std::string mnt(Pathname(e->dir).asString());
00896 std::string our(path.asString());
00897
00898 if( our == mnt)
00899 {
00900
00901 return false;
00902 }
00903 else
00904 if( mnt.size() > our.size() &&
00905 mnt.at(our.size()) == '/' &&
00906 !mnt.compare(0, our.size(), our))
00907 {
00908
00909
00910 return false;
00911 }
00912 }
00913
00914 return true;
00915 }
00916
00917
00918 AttachedMedia
00919 MediaManager::getAttachedMedia(MediaAccessId &accessId) const
00920 {
00921 MutexLock glock(g_Mutex);
00922
00923 ManagedMedia &ref( m_impl->findMM(accessId));
00924
00925 return ref.handler->attachedMedia();
00926 }
00927
00928
00929 AttachedMedia
00930 MediaManager::findAttachedMedia(const MediaSourceRef &media) const
00931 {
00932 MutexLock glock(g_Mutex);
00933
00934 if( !media || media->type.empty())
00935 return AttachedMedia();
00936
00937 ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
00938 for( ; m != m_impl->mediaMap.end(); ++m)
00939 {
00940 if( !m->second.handler->isAttached())
00941 continue;
00942
00943 AttachedMedia ret = m->second.handler->attachedMedia();
00944 if( ret.mediaSource && ret.mediaSource->equals( *media))
00945 return ret;
00946 }
00947 return AttachedMedia();
00948 }
00949
00950
00951 void
00952 MediaManager::forceReleaseShared(const MediaSourceRef &media)
00953 {
00954 MutexLock glock(g_Mutex);
00955
00956 if( !media || media->type.empty())
00957 return;
00958
00959 ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00960 for( ; m != m_impl->mediaMap.end(); ++m)
00961 {
00962 if( !m->second.handler->isAttached())
00963 continue;
00964
00965 AttachedMedia ret = m->second.handler->attachedMedia();
00966 if( ret.mediaSource && ret.mediaSource->equals( *media))
00967 {
00968 m->second.handler->release();
00969 m->second.desired = false;
00970 }
00971 }
00972 }
00973
00975 }
00977
00979 }
00981
00982
00983