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