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 time_t mtime = zypp::PathInfo("/etc/mtab").mtime();
00364 if( mtime <= 0)
00365 {
00366 WAR << "Failed to retrieve modification time of '/etc/mtab'"
00367 << std::endl;
00368 }
00369 return mtime;
00370 }
00371
00372 static inline MountEntries
00373 getMountEntries()
00374 {
00375
00376
00377 return Mount::getEntries();
00378 }
00379
00380 };
00381
00382
00384
00385 zypp::RW_pointer<MediaManager_Impl> MediaManager::m_impl(NULL);
00386
00387
00389 MediaManager::MediaManager()
00390 {
00391 MutexLock glock(g_Mutex);
00392 if( !m_impl)
00393 {
00394 m_impl.reset( new MediaManager_Impl());
00395 }
00396 }
00397
00398
00399 MediaManager::~MediaManager()
00400 {
00401 }
00402
00403
00404 MediaAccessId
00405 MediaManager::open(const Url &url, const Pathname &preferred_attach_point)
00406 {
00407 MutexLock glock(g_Mutex);
00408
00409
00410 MediaAccessRef handler( new MediaAccess());
00411 MediaVerifierRef verifier( new NoVerifier());
00412 ManagedMedia tmp( handler, verifier);
00413
00414 tmp.handler->open(url, preferred_attach_point);
00415
00416 MediaAccessId nextId = m_impl->nextAccessId();
00417
00418 m_impl->mediaMap[nextId] = tmp;
00419
00420 DBG << "Opened new media access using id " << nextId
00421 << " to " << url.asString() << std::endl;
00422 return nextId;
00423 }
00424
00425
00426 void
00427 MediaManager::close(MediaAccessId accessId)
00428 {
00429 MutexLock glock(g_Mutex);
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441 ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00442 for( ; m != m_impl->mediaMap.end(); ++m)
00443 {
00444 if( m->second.handler->dependsOnParent(accessId, true))
00445 {
00446 ZYPP_THROW(MediaIsSharedException(
00447 m->second.handler->url().asString()
00448 ));
00449 }
00450 }
00451
00452 DBG << "Close to access handler using id "
00453 << accessId << " requested" << std::endl;
00454
00455 ManagedMedia &ref( m_impl->findMM(accessId));
00456 ref.handler->close();
00457
00458 m_impl->mediaMap.erase(accessId);
00459 }
00460
00461
00462 bool
00463 MediaManager::isOpen(MediaAccessId accessId) const
00464 {
00465 MutexLock glock(g_Mutex);
00466
00467 ManagedMediaMap::iterator it( m_impl->mediaMap.find(accessId));
00468 return it != m_impl->mediaMap.end() &&
00469 it->second.handler->isOpen();
00470 }
00471
00472
00473 std::string
00474 MediaManager::protocol(MediaAccessId accessId) const
00475 {
00476 MutexLock glock(g_Mutex);
00477
00478 ManagedMedia &ref( m_impl->findMM(accessId));
00479
00480 return ref.handler->protocol();
00481 }
00482
00483
00484 bool
00485 MediaManager::downloads(MediaAccessId accessId) const
00486 {
00487 MutexLock glock(g_Mutex);
00488
00489 ManagedMedia &ref( m_impl->findMM(accessId));
00490
00491 return ref.handler->downloads();
00492 }
00493
00494
00495
00496 bool
00497 MediaManager::downloads(const Url &url)
00498 {
00499 return MediaAccess::downloads( url);
00500 }
00501
00502
00503 Url
00504 MediaManager::url(MediaAccessId accessId) const
00505 {
00506 MutexLock glock(g_Mutex);
00507
00508 ManagedMedia &ref( m_impl->findMM(accessId));
00509
00510 return ref.handler->url();
00511 }
00512
00513
00514 void
00515 MediaManager::addVerifier(MediaAccessId accessId,
00516 const MediaVerifierRef &verifier)
00517 {
00518 MutexLock glock(g_Mutex);
00519
00520 if( !verifier)
00521 ZYPP_THROW(MediaException("Invalid verifier reference"));
00522
00523 ManagedMedia &ref( m_impl->findMM(accessId));
00524
00525 ref.desired = false;
00526 MediaVerifierRef(verifier).swap(ref.verifier);
00527
00528 DBG << "MediaVerifier change: id=" << accessId << ", verifier="
00529 << verifier->info() << std::endl;
00530 }
00531
00532
00533 void
00534 MediaManager::delVerifier(MediaAccessId accessId)
00535 {
00536 MutexLock glock(g_Mutex);
00537
00538 ManagedMedia &ref( m_impl->findMM(accessId));
00539
00540 MediaVerifierRef verifier( new NoVerifier());
00541 ref.desired = false;
00542 ref.verifier.swap(verifier);
00543
00544 DBG << "MediaVerifier change: id=" << accessId << ", verifier="
00545 << verifier->info() << std::endl;
00546 }
00547
00548
00549 bool
00550 MediaManager::setAttachPrefix(const Pathname &attach_prefix)
00551 {
00552 MutexLock glock(g_Mutex);
00553
00554 return MediaHandler::setAttachPrefix(attach_prefix);
00555 }
00556
00557
00558 void
00559 MediaManager::attach(MediaAccessId accessId, bool next)
00560 {
00561 MutexLock glock(g_Mutex);
00562
00563 ManagedMedia &ref( m_impl->findMM(accessId));
00564
00565 DBG << "attach(id=" << accessId << ")" << std::endl;
00566 return ref.handler->attach(next);
00567 }
00568
00569
00570 void
00571 MediaManager::release(MediaAccessId accessId, bool eject)
00572 {
00573 MutexLock glock(g_Mutex);
00574
00575 ManagedMedia &ref( m_impl->findMM(accessId));
00576
00577 DBG << "release(id=" << accessId
00578 << (eject ? ", eject)" : ")") << std::endl;
00579 if( eject)
00580 {
00581
00582
00583
00584
00585
00586
00587 ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00588 for( ; m != m_impl->mediaMap.end(); ++m)
00589 {
00590 if( m->second.handler->dependsOnParent(accessId, false))
00591 {
00592 try
00593 {
00594 DBG << "Forcing release of handler depending on access id "
00595 << accessId << std::endl;
00596 m->second.desired = false;
00597 m->second.handler->release(!eject);
00598 }
00599 catch(const MediaException &e)
00600 {
00601 ZYPP_CAUGHT(e);
00602 }
00603 }
00604 }
00605 }
00606 ref.desired = false;
00607 ref.handler->release(eject);
00608 }
00609
00610
00611 void
00612 MediaManager::disconnect(MediaAccessId accessId)
00613 {
00614 MutexLock glock(g_Mutex);
00615
00616 ManagedMedia &ref( m_impl->findMM(accessId));
00617
00618 ref.handler->disconnect();
00619 }
00620
00621
00622 bool
00623 MediaManager::isAttached(MediaAccessId accessId) const
00624 {
00625 MutexLock glock(g_Mutex);
00626
00627 ManagedMedia &ref( m_impl->findMM(accessId));
00628
00629 return ref.handler->isAttached();
00630 }
00631
00632
00633 bool MediaManager::isSharedMedia(MediaAccessId accessId) const
00634 {
00635 MutexLock glock(g_Mutex);
00636
00637 ManagedMedia &ref( m_impl->findMM(accessId));
00638
00639 return ref.handler->isSharedMedia();
00640 }
00641
00642
00643 bool
00644 MediaManager::isDesiredMedia(MediaAccessId accessId) const
00645 {
00646 MutexLock glock(g_Mutex);
00647
00648 ManagedMedia &ref( m_impl->findMM(accessId));
00649
00650 if( !ref.handler->isAttached())
00651 {
00652 ref.desired = false;
00653 }
00654 else
00655 {
00656 try {
00657 ref.desired = ref.verifier->isDesiredMedia(ref.handler);
00658 }
00659 catch(const zypp::Exception &e) {
00660 ZYPP_CAUGHT(e);
00661 ref.desired = false;
00662 }
00663 }
00664 DBG << "isDesiredMedia(" << accessId << "): "
00665 << (ref.desired ? "" : "not ")
00666 << "desired (report by "
00667 << ref.verifier->info() << ")" << std::endl;
00668 return ref.desired;
00669 }
00670
00671
00672 bool
00673 MediaManager::isDesiredMedia(MediaAccessId accessId,
00674 const MediaVerifierRef &verifier) const
00675 {
00676 MutexLock glock(g_Mutex);
00677
00678 MediaVerifierRef v(verifier);
00679 if( !v)
00680 ZYPP_THROW(MediaException("Invalid verifier reference"));
00681
00682 ManagedMedia &ref( m_impl->findMM(accessId));
00683
00684 bool desired = false;
00685 if( ref.handler->isAttached())
00686 {
00687 try {
00688 desired = v->isDesiredMedia(ref.handler);
00689 }
00690 catch(const zypp::Exception &e) {
00691 ZYPP_CAUGHT(e);
00692 desired = false;
00693 }
00694 }
00695 DBG << "isDesiredMedia(" << accessId << "): "
00696 << (desired ? "" : "not ")
00697 << "desired (report by "
00698 << v->info() << ")" << std::endl;
00699 return desired;
00700 }
00701
00702
00703 Pathname
00704 MediaManager::localRoot(MediaAccessId accessId) const
00705 {
00706 MutexLock glock(g_Mutex);
00707
00708 ManagedMedia &ref( m_impl->findMM(accessId));
00709
00710 Pathname path;
00711 path = ref.handler->localRoot();
00712 return path;
00713 }
00714
00715
00716 Pathname
00717 MediaManager::localPath(MediaAccessId accessId,
00718 const Pathname & pathname) const
00719 {
00720 MutexLock glock(g_Mutex);
00721
00722 ManagedMedia &ref( m_impl->findMM(accessId));
00723
00724 Pathname path;
00725 path = ref.handler->localPath(pathname);
00726 return path;
00727 }
00728
00729
00730 void
00731 MediaManager::provideFile(MediaAccessId accessId,
00732 const Pathname &filename,
00733 bool cached,
00734 bool checkonly) const
00735 {
00736 MutexLock glock(g_Mutex);
00737
00738 ManagedMedia &ref( m_impl->findMM(accessId));
00739
00740 ref.checkDesired(accessId);
00741
00742 ref.handler->provideFile(filename, cached, checkonly);
00743 }
00744
00745
00746 void
00747 MediaManager::provideDir(MediaAccessId accessId,
00748 const Pathname &dirname) const
00749 {
00750 MutexLock glock(g_Mutex);
00751
00752 ManagedMedia &ref( m_impl->findMM(accessId));
00753
00754 ref.checkDesired(accessId);
00755
00756 ref.handler->provideDir(dirname);
00757 }
00758
00759
00760 void
00761 MediaManager::provideDirTree(MediaAccessId accessId,
00762 const Pathname &dirname) const
00763 {
00764 MutexLock glock(g_Mutex);
00765
00766 ManagedMedia &ref( m_impl->findMM(accessId));
00767
00768 ref.checkDesired(accessId);
00769
00770 ref.handler->provideDirTree(dirname);
00771 }
00772
00773
00774 void
00775 MediaManager::releaseFile(MediaAccessId accessId,
00776 const Pathname &filename) const
00777 {
00778 MutexLock glock(g_Mutex);
00779
00780 ManagedMedia &ref( m_impl->findMM(accessId));
00781
00782 ref.checkAttached(accessId);
00783
00784 ref.handler->releaseFile(filename);
00785 }
00786
00787
00788 void
00789 MediaManager::releaseDir(MediaAccessId accessId,
00790 const Pathname &dirname) const
00791 {
00792 MutexLock glock(g_Mutex);
00793
00794 ManagedMedia &ref( m_impl->findMM(accessId));
00795
00796 ref.checkAttached(accessId);
00797
00798 ref.handler->releaseDir(dirname);
00799 }
00800
00801
00802
00803 void
00804 MediaManager::releasePath(MediaAccessId accessId,
00805 const Pathname &pathname) const
00806 {
00807 MutexLock glock(g_Mutex);
00808
00809 ManagedMedia &ref( m_impl->findMM(accessId));
00810
00811 ref.checkAttached(accessId);
00812
00813 ref.handler->releasePath(pathname);
00814 }
00815
00816
00817 void
00818 MediaManager::dirInfo(MediaAccessId accessId,
00819 std::list<std::string> &retlist,
00820 const Pathname &dirname,
00821 bool dots) const
00822 {
00823 MutexLock glock(g_Mutex);
00824
00825 ManagedMedia &ref( m_impl->findMM(accessId));
00826
00827
00828 ref.checkAttached(accessId);
00829
00830 ref.handler->dirInfo(retlist, dirname, dots);
00831 }
00832
00833
00834 void
00835 MediaManager::dirInfo(MediaAccessId accessId,
00836 filesystem::DirContent &retlist,
00837 const Pathname &dirname,
00838 bool dots) const
00839 {
00840 MutexLock glock(g_Mutex);
00841
00842 ManagedMedia &ref( m_impl->findMM(accessId));
00843
00844
00845 ref.checkAttached(accessId);
00846
00847 ref.handler->dirInfo(retlist, dirname, dots);
00848 }
00849
00850
00851
00852 time_t
00853 MediaManager::getMountTableMTime()
00854 {
00855 MutexLock glock(g_Mutex);
00856 return MediaManager_Impl::getMountTableMTime();
00857 }
00858
00859
00860
00861 MountEntries
00862 MediaManager::getMountEntries()
00863 {
00864 MutexLock glock(g_Mutex);
00865
00866 return MediaManager_Impl::getMountEntries();
00867 }
00868
00869
00870 bool
00871 MediaManager::isUseableAttachPoint(const Pathname &path,
00872 bool mtab) const
00873 {
00874 if( path.empty() || path == "/" || !PathInfo(path).isDir())
00875 return false;
00876
00877 MutexLock glock(g_Mutex);
00878
00879
00880
00881
00882 ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
00883 for( ; m != m_impl->mediaMap.end(); ++m)
00884 {
00885 AttachedMedia ret = m->second.handler->attachedMedia();
00886 if( ret.mediaSource && ret.attachPoint)
00887 {
00888 std::string mnt(ret.attachPoint->path.asString());
00889 std::string our(path.asString());
00890
00891 if( our == mnt)
00892 {
00893
00894 return false;
00895 }
00896 else
00897 if( mnt.size() > our.size() &&
00898 mnt.at(our.size()) == '/' &&
00899 !mnt.compare(0, our.size(), our))
00900 {
00901
00902
00903 return false;
00904 }
00905 }
00906 }
00907
00908 if( !mtab)
00909 return true;
00910
00911
00912
00913
00914 MountEntries entries( m_impl->getMountEntries());
00915 MountEntries::const_iterator e;
00916 for( e = entries.begin(); e != entries.end(); ++e)
00917 {
00918 std::string mnt(Pathname(e->dir).asString());
00919 std::string our(path.asString());
00920
00921 if( our == mnt)
00922 {
00923
00924 return false;
00925 }
00926 else
00927 if( mnt.size() > our.size() &&
00928 mnt.at(our.size()) == '/' &&
00929 !mnt.compare(0, our.size(), our))
00930 {
00931
00932
00933 return false;
00934 }
00935 }
00936
00937 return true;
00938 }
00939
00940
00941 AttachedMedia
00942 MediaManager::getAttachedMedia(MediaAccessId &accessId) const
00943 {
00944 MutexLock glock(g_Mutex);
00945
00946 ManagedMedia &ref( m_impl->findMM(accessId));
00947
00948 return ref.handler->attachedMedia();
00949 }
00950
00951
00952 AttachedMedia
00953 MediaManager::findAttachedMedia(const MediaSourceRef &media) const
00954 {
00955 MutexLock glock(g_Mutex);
00956
00957 if( !media || media->type.empty())
00958 return AttachedMedia();
00959
00960 ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
00961 for( ; m != m_impl->mediaMap.end(); ++m)
00962 {
00963 if( !m->second.handler->isAttached())
00964 continue;
00965
00966 AttachedMedia ret = m->second.handler->attachedMedia();
00967 if( ret.mediaSource && ret.mediaSource->equals( *media))
00968 return ret;
00969 }
00970 return AttachedMedia();
00971 }
00972
00973
00974 void
00975 MediaManager::forceReleaseShared(const MediaSourceRef &media)
00976 {
00977 MutexLock glock(g_Mutex);
00978
00979 if( !media || media->type.empty())
00980 return;
00981
00982 ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00983 for( ; m != m_impl->mediaMap.end(); ++m)
00984 {
00985 if( !m->second.handler->isAttached())
00986 continue;
00987
00988 AttachedMedia ret = m->second.handler->attachedMedia();
00989 if( ret.mediaSource && ret.mediaSource->equals( *media))
00990 {
00991 m->second.handler->release(false);
00992 m->second.desired = false;
00993 }
00994 }
00995 }
00996
00998 }
01000
01002 }
01004
01005
01006