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