mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	Refine resource manager, ignore unsubscribed handler
This commit is contained in:
		
							parent
							
								
									c120e954f5
								
							
						
					
					
						commit
						776f24cf3d
					
				
					 4 changed files with 214 additions and 28 deletions
				
			
		| 
						 | 
					@ -32,6 +32,7 @@ using namespace std;
 | 
				
			||||||
#include <srs_app_utility.hpp>
 | 
					#include <srs_app_utility.hpp>
 | 
				
			||||||
#include <srs_kernel_utility.hpp>
 | 
					#include <srs_kernel_utility.hpp>
 | 
				
			||||||
#include <srs_service_log.hpp>
 | 
					#include <srs_service_log.hpp>
 | 
				
			||||||
 | 
					#include <srs_app_log.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ISrsDisposingHandler::ISrsDisposingHandler()
 | 
					ISrsDisposingHandler::ISrsDisposingHandler()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -48,6 +49,7 @@ SrsResourceManager::SrsResourceManager(const std::string& label, bool verbose)
 | 
				
			||||||
    cond = srs_cond_new();
 | 
					    cond = srs_cond_new();
 | 
				
			||||||
    trd = NULL;
 | 
					    trd = NULL;
 | 
				
			||||||
    p_disposing_ = NULL;
 | 
					    p_disposing_ = NULL;
 | 
				
			||||||
 | 
					    removing_ = false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SrsResourceManager::~SrsResourceManager()
 | 
					SrsResourceManager::~SrsResourceManager()
 | 
				
			||||||
| 
						 | 
					@ -151,6 +153,12 @@ void SrsResourceManager::subscribe(ISrsDisposingHandler* h)
 | 
				
			||||||
    if (std::find(handlers_.begin(), handlers_.end(), h) == handlers_.end()) {
 | 
					    if (std::find(handlers_.begin(), handlers_.end(), h) == handlers_.end()) {
 | 
				
			||||||
        handlers_.push_back(h);
 | 
					        handlers_.push_back(h);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Restore the handler from unsubscribing handlers.
 | 
				
			||||||
 | 
					    vector<ISrsDisposingHandler*>::iterator it;
 | 
				
			||||||
 | 
					    if ((it = std::find(unsubs_.begin(), unsubs_.end(), h)) != unsubs_.end()) {
 | 
				
			||||||
 | 
					        unsubs_.erase(it);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SrsResourceManager::unsubscribe(ISrsDisposingHandler* h)
 | 
					void SrsResourceManager::unsubscribe(ISrsDisposingHandler* h)
 | 
				
			||||||
| 
						 | 
					@ -159,9 +167,21 @@ void SrsResourceManager::unsubscribe(ISrsDisposingHandler* h)
 | 
				
			||||||
    if (it != handlers_.end()) {
 | 
					    if (it != handlers_.end()) {
 | 
				
			||||||
        handlers_.erase(it);
 | 
					        handlers_.erase(it);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Put it to the unsubscribing handlers.
 | 
				
			||||||
 | 
					    if (std::find(unsubs_.begin(), unsubs_.end(), h) == unsubs_.end()) {
 | 
				
			||||||
 | 
					        unsubs_.push_back(h);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SrsResourceManager::remove(ISrsResource* c)
 | 
					void SrsResourceManager::remove(ISrsResource* c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    removing_ = true;
 | 
				
			||||||
 | 
					    do_remove(c);
 | 
				
			||||||
 | 
					    removing_ = false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SrsResourceManager::do_remove(ISrsResource* c)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    SrsContextRestore(cid_);
 | 
					    SrsContextRestore(cid_);
 | 
				
			||||||
    if (verbose_) {
 | 
					    if (verbose_) {
 | 
				
			||||||
| 
						 | 
					@ -186,9 +206,19 @@ void SrsResourceManager::remove(ISrsResource* c)
 | 
				
			||||||
    // Push to zombies, we will free it in another coroutine.
 | 
					    // Push to zombies, we will free it in another coroutine.
 | 
				
			||||||
    zombies_.push_back(c);
 | 
					    zombies_.push_back(c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // We should copy all handlers, because it may change during callback.
 | 
				
			||||||
 | 
					    vector<ISrsDisposingHandler*> handlers = handlers_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Notify other handlers to handle the before-dispose event.
 | 
					    // Notify other handlers to handle the before-dispose event.
 | 
				
			||||||
    for (int i = 0; i < (int)handlers_.size(); i++) {
 | 
					    for (int i = 0; i < (int)handlers.size(); i++) {
 | 
				
			||||||
        ISrsDisposingHandler* h = handlers_.at(i);
 | 
					        ISrsDisposingHandler* h = handlers.at(i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Ignore if handler is unsubscribing.
 | 
				
			||||||
 | 
					        if (!unsubs_.empty() && std::find(unsubs_.begin(), unsubs_.end(), h) != unsubs_.end()) {
 | 
				
			||||||
 | 
					            srs_warn2(TAG_RESOURCE_UNSUB, "ignore before-dispose for %p", h);
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        h->on_before_dispose(c);
 | 
					        h->on_before_dispose(c);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -207,6 +237,11 @@ void SrsResourceManager::clear()
 | 
				
			||||||
        srs_trace("clear zombies=%d connections", (int)zombies_.size());
 | 
					        srs_trace("clear zombies=%d connections", (int)zombies_.size());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Clear all unsubscribing handlers, if not removing any resource.
 | 
				
			||||||
 | 
					    if (!removing_ && !unsubs_.empty()) {
 | 
				
			||||||
 | 
					        vector<ISrsDisposingHandler*>().swap(unsubs_);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    do_clear();
 | 
					    do_clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Reset it for it points to a local object.
 | 
					    // Reset it for it points to a local object.
 | 
				
			||||||
| 
						 | 
					@ -260,8 +295,19 @@ void SrsResourceManager::dispose(ISrsResource* c)
 | 
				
			||||||
        conns_.erase(it);
 | 
					        conns_.erase(it);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (int i = 0; i < (int)handlers_.size(); i++) {
 | 
					    // We should copy all handlers, because it may change during callback.
 | 
				
			||||||
        ISrsDisposingHandler* h = handlers_.at(i);
 | 
					    vector<ISrsDisposingHandler*> handlers = handlers_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Notify other handlers to handle the disposing event.
 | 
				
			||||||
 | 
					    for (int i = 0; i < (int)handlers.size(); i++) {
 | 
				
			||||||
 | 
					        ISrsDisposingHandler* h = handlers.at(i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Ignore if handler is unsubscribing.
 | 
				
			||||||
 | 
					        if (!unsubs_.empty() && std::find(unsubs_.begin(), unsubs_.end(), h) != unsubs_.end()) {
 | 
				
			||||||
 | 
					            srs_warn2(TAG_RESOURCE_UNSUB, "ignore disposing for %p", h);
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        h->on_disposing(c);
 | 
					        h->on_disposing(c);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,6 +62,10 @@ private:
 | 
				
			||||||
    srs_cond_t cond;
 | 
					    srs_cond_t cond;
 | 
				
			||||||
    // Callback handlers.
 | 
					    // Callback handlers.
 | 
				
			||||||
    std::vector<ISrsDisposingHandler*> handlers_;
 | 
					    std::vector<ISrsDisposingHandler*> handlers_;
 | 
				
			||||||
 | 
					    // Unsubscribing handlers, skip it for notifying.
 | 
				
			||||||
 | 
					    std::vector<ISrsDisposingHandler*> unsubs_;
 | 
				
			||||||
 | 
					    // Whether we are removing resources.
 | 
				
			||||||
 | 
					    bool removing_;
 | 
				
			||||||
    // The zombie connections, we will delete it asynchronously.
 | 
					    // The zombie connections, we will delete it asynchronously.
 | 
				
			||||||
    std::vector<ISrsResource*> zombies_;
 | 
					    std::vector<ISrsResource*> zombies_;
 | 
				
			||||||
    std::vector<ISrsResource*>* p_disposing_;
 | 
					    std::vector<ISrsResource*>* p_disposing_;
 | 
				
			||||||
| 
						 | 
					@ -96,6 +100,7 @@ public:
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    virtual void remove(ISrsResource* c);
 | 
					    virtual void remove(ISrsResource* c);
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					    void do_remove(ISrsResource* c);
 | 
				
			||||||
    void clear();
 | 
					    void clear();
 | 
				
			||||||
    void do_clear();
 | 
					    void do_clear();
 | 
				
			||||||
    void dispose(ISrsResource* c);
 | 
					    void dispose(ISrsResource* c);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,7 +35,8 @@
 | 
				
			||||||
// For log TAGs.
 | 
					// For log TAGs.
 | 
				
			||||||
#define TAG_MAIN "MAIN"
 | 
					#define TAG_MAIN "MAIN"
 | 
				
			||||||
#define TAG_MAYBE "MAYBE"
 | 
					#define TAG_MAYBE "MAYBE"
 | 
				
			||||||
#define TAG_DTLS_ALERT "DTLSALERT"
 | 
					#define TAG_DTLS_ALERT "DTLS_ALERT"
 | 
				
			||||||
 | 
					#define TAG_RESOURCE_UNSUB "RESOURCE_UNSUB"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Use memory/disk cache and donot flush when write log.
 | 
					// Use memory/disk cache and donot flush when write log.
 | 
				
			||||||
// it's ok to use it without config, which will log to console, and default trace level.
 | 
					// it's ok to use it without config, which will log to console, and default trace level.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,25 +37,20 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
using namespace std;
 | 
					using namespace std;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MockResourceHookOwner : public ISrsResource, public ISrsDisposingHandler
 | 
					class MockResource : public ISrsDisposingHandler, public ISrsResource
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    ISrsResource* owner_;
 | 
					 | 
				
			||||||
    SrsResourceManager* manager_;
 | 
					    SrsResourceManager* manager_;
 | 
				
			||||||
    MockResourceHookOwner(SrsResourceManager* manager) {
 | 
					    MockResource(SrsResourceManager* manager) {
 | 
				
			||||||
        manager_ = manager;
 | 
					        manager_ = manager;
 | 
				
			||||||
        owner_ = NULL;
 | 
					        if (manager_) {
 | 
				
			||||||
            manager_->subscribe(this);
 | 
					            manager_->subscribe(this);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    virtual ~MockResourceHookOwner() {
 | 
					    }
 | 
				
			||||||
 | 
					    virtual ~MockResource() {
 | 
				
			||||||
 | 
					        if (manager_) {
 | 
				
			||||||
            manager_->unsubscribe(this);
 | 
					            manager_->unsubscribe(this);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    virtual void on_before_dispose(ISrsResource* c) {
 | 
					 | 
				
			||||||
        if (c == owner_) { // Remove self if its owner is disposing.
 | 
					 | 
				
			||||||
            manager_->remove(this);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    virtual void on_disposing(ISrsResource* c) {
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    virtual const SrsContextId& get_id() {
 | 
					    virtual const SrsContextId& get_id() {
 | 
				
			||||||
        return _srs_context->get_id();
 | 
					        return _srs_context->get_id();
 | 
				
			||||||
| 
						 | 
					@ -65,19 +60,33 @@ public:
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MockResourceSelf : public ISrsResource, public ISrsDisposingHandler
 | 
					class MockResourceHookOwner : public MockResource
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    ISrsResource* owner_;
 | 
				
			||||||
 | 
					    MockResourceHookOwner(SrsResourceManager* manager) : MockResource(manager) {
 | 
				
			||||||
 | 
					        owner_ = NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    virtual ~MockResourceHookOwner() {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    virtual void on_before_dispose(ISrsResource* c) {
 | 
				
			||||||
 | 
					        if (c == owner_) { // Remove self if its owner is disposing.
 | 
				
			||||||
 | 
					            manager_->remove(this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    virtual void on_disposing(ISrsResource* c) {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MockResourceSelf : public MockResource
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    bool remove_in_before_dispose;
 | 
					    bool remove_in_before_dispose;
 | 
				
			||||||
    bool remove_in_disposing;
 | 
					    bool remove_in_disposing;
 | 
				
			||||||
    SrsResourceManager* manager_;
 | 
					    MockResourceSelf(SrsResourceManager* manager) : MockResource(manager) {
 | 
				
			||||||
    MockResourceSelf(SrsResourceManager* manager) {
 | 
					 | 
				
			||||||
        remove_in_before_dispose = remove_in_disposing = false;
 | 
					        remove_in_before_dispose = remove_in_disposing = false;
 | 
				
			||||||
        manager_ = manager;
 | 
					 | 
				
			||||||
        manager_->subscribe(this);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    virtual ~MockResourceSelf() {
 | 
					    virtual ~MockResourceSelf() {
 | 
				
			||||||
        manager_->unsubscribe(this);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    virtual void on_before_dispose(ISrsResource* c) {
 | 
					    virtual void on_before_dispose(ISrsResource* c) {
 | 
				
			||||||
        if (remove_in_before_dispose) {
 | 
					        if (remove_in_before_dispose) {
 | 
				
			||||||
| 
						 | 
					@ -89,11 +98,37 @@ public:
 | 
				
			||||||
            manager_->remove(this);
 | 
					            manager_->remove(this);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    virtual const SrsContextId& get_id() {
 | 
					};
 | 
				
			||||||
        return _srs_context->get_id();
 | 
					
 | 
				
			||||||
 | 
					class MockResourceUnsubscribe : public MockResource
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    int nn_before_dispose;
 | 
				
			||||||
 | 
					    int nn_disposing;
 | 
				
			||||||
 | 
					    bool unsubscribe_in_before_dispose;
 | 
				
			||||||
 | 
					    bool unsubscribe_in_disposing;
 | 
				
			||||||
 | 
					    MockResourceUnsubscribe* result;
 | 
				
			||||||
 | 
					    MockResourceUnsubscribe(SrsResourceManager* manager) : MockResource(manager) {
 | 
				
			||||||
 | 
					        unsubscribe_in_before_dispose = unsubscribe_in_disposing = false;
 | 
				
			||||||
 | 
					        nn_before_dispose = nn_disposing = 0;
 | 
				
			||||||
 | 
					        result = NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    virtual ~MockResourceUnsubscribe() {
 | 
				
			||||||
 | 
					        if (result) { // Copy result before disposing it.
 | 
				
			||||||
 | 
					            *result = *this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    virtual void on_before_dispose(ISrsResource* c) {
 | 
				
			||||||
 | 
					        nn_before_dispose++;
 | 
				
			||||||
 | 
					        if (unsubscribe_in_before_dispose) {
 | 
				
			||||||
 | 
					            manager_->unsubscribe(this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    virtual void on_disposing(ISrsResource* c) {
 | 
				
			||||||
 | 
					        nn_disposing++;
 | 
				
			||||||
 | 
					        if (unsubscribe_in_disposing) {
 | 
				
			||||||
 | 
					            manager_->unsubscribe(this);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    virtual std::string desc() {
 | 
					 | 
				
			||||||
        return "";
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -101,6 +136,105 @@ VOID TEST(KernelRTCTest, ConnectionManagerTest)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    srs_error_t err = srs_success;
 | 
					    srs_error_t err = srs_success;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // When notifying, the handlers changed, disposing event may lost.
 | 
				
			||||||
 | 
					    if (true) {
 | 
				
			||||||
 | 
					        SrsResourceManager manager("mgr");
 | 
				
			||||||
 | 
					        HELPER_EXPECT_SUCCESS(manager.start());
 | 
				
			||||||
 | 
					        EXPECT_EQ(0, manager.size()); EXPECT_TRUE(manager.empty());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        MockResourceUnsubscribe* conn0 = new MockResourceUnsubscribe(&manager);
 | 
				
			||||||
 | 
					        conn0->unsubscribe_in_disposing = true;
 | 
				
			||||||
 | 
					        manager.add(conn0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        MockResourceUnsubscribe* conn1 = new MockResourceUnsubscribe(&manager);
 | 
				
			||||||
 | 
					        manager.add(conn1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        MockResourceUnsubscribe* conn2 = new MockResourceUnsubscribe(&manager);
 | 
				
			||||||
 | 
					        manager.add(conn2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // When removing conn0, it will unsubscribe and change the handlers,
 | 
				
			||||||
 | 
					        // which should not cause the conn1 lost event.
 | 
				
			||||||
 | 
					        manager.remove(conn0);
 | 
				
			||||||
 | 
					        srs_usleep(0);
 | 
				
			||||||
 | 
					        ASSERT_EQ(2, manager.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        EXPECT_EQ(1, conn1->nn_before_dispose);
 | 
				
			||||||
 | 
					        EXPECT_EQ(1, conn1->nn_disposing); // Should get event.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        EXPECT_EQ(1, conn2->nn_before_dispose);
 | 
				
			||||||
 | 
					        EXPECT_EQ(1, conn2->nn_disposing);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // When notifying, the handlers changed, before-dispose event may lost.
 | 
				
			||||||
 | 
					    if (true) {
 | 
				
			||||||
 | 
					        SrsResourceManager manager("mgr");
 | 
				
			||||||
 | 
					        HELPER_EXPECT_SUCCESS(manager.start());
 | 
				
			||||||
 | 
					        EXPECT_EQ(0, manager.size()); EXPECT_TRUE(manager.empty());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        MockResourceUnsubscribe* conn0 = new MockResourceUnsubscribe(&manager);
 | 
				
			||||||
 | 
					        conn0->unsubscribe_in_before_dispose = true;
 | 
				
			||||||
 | 
					        manager.add(conn0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        MockResourceUnsubscribe* conn1 = new MockResourceUnsubscribe(&manager);
 | 
				
			||||||
 | 
					        manager.add(conn1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        MockResourceUnsubscribe* conn2 = new MockResourceUnsubscribe(&manager);
 | 
				
			||||||
 | 
					        manager.add(conn2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // When removing conn0, it will unsubscribe and change the handlers,
 | 
				
			||||||
 | 
					        // which should not cause the conn1 lost event.
 | 
				
			||||||
 | 
					        manager.remove(conn0);
 | 
				
			||||||
 | 
					        srs_usleep(0);
 | 
				
			||||||
 | 
					        ASSERT_EQ(2, manager.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        EXPECT_EQ(1, conn1->nn_before_dispose); // Should get event.
 | 
				
			||||||
 | 
					        EXPECT_EQ(1, conn1->nn_disposing);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        EXPECT_EQ(1, conn2->nn_before_dispose);
 | 
				
			||||||
 | 
					        EXPECT_EQ(1, conn2->nn_disposing);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Subscribe or unsubscribe for multiple times.
 | 
				
			||||||
 | 
					    if (true) {
 | 
				
			||||||
 | 
					        SrsResourceManager manager("mgr");
 | 
				
			||||||
 | 
					        HELPER_EXPECT_SUCCESS(manager.start());
 | 
				
			||||||
 | 
					        EXPECT_EQ(0, manager.size()); EXPECT_TRUE(manager.empty());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        MockResourceUnsubscribe* resource = new MockResourceUnsubscribe(&manager);
 | 
				
			||||||
 | 
					        resource->unsubscribe_in_before_dispose = true;
 | 
				
			||||||
 | 
					        manager.add(resource);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        MockResourceUnsubscribe result(NULL); // No manager for result.
 | 
				
			||||||
 | 
					        resource->result = &result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        manager.remove(resource);
 | 
				
			||||||
 | 
					        srs_usleep(0);
 | 
				
			||||||
 | 
					        ASSERT_EQ(0, manager.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        EXPECT_EQ(1, result.nn_before_dispose);
 | 
				
			||||||
 | 
					        EXPECT_EQ(0, result.nn_disposing); // No disposing event, because we unsubscribe in before-dispose.
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Count the event for disposing.
 | 
				
			||||||
 | 
					    if (true) {
 | 
				
			||||||
 | 
					        SrsResourceManager manager("mgr");
 | 
				
			||||||
 | 
					        HELPER_EXPECT_SUCCESS(manager.start());
 | 
				
			||||||
 | 
					        EXPECT_EQ(0, manager.size()); EXPECT_TRUE(manager.empty());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        MockResourceUnsubscribe* resource = new MockResourceUnsubscribe(&manager);
 | 
				
			||||||
 | 
					        manager.add(resource);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        MockResourceUnsubscribe result(NULL); // No manager for result.
 | 
				
			||||||
 | 
					        resource->result = &result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        manager.remove(resource);
 | 
				
			||||||
 | 
					        srs_usleep(0);
 | 
				
			||||||
 | 
					        ASSERT_EQ(0, manager.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        EXPECT_EQ(1, result.nn_before_dispose);
 | 
				
			||||||
 | 
					        EXPECT_EQ(1, result.nn_disposing);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // When hooks disposing, remove itself again.
 | 
					    // When hooks disposing, remove itself again.
 | 
				
			||||||
    if (true) {
 | 
					    if (true) {
 | 
				
			||||||
        SrsResourceManager manager("mgr");
 | 
					        SrsResourceManager manager("mgr");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue