Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Leak with subject? #242

Open
diorcety opened this issue Aug 4, 2016 · 3 comments
Open

Leak with subject? #242

diorcety opened this issue Aug 4, 2016 · 3 comments

Comments

@diorcety
Copy link
Contributor

diorcety commented Aug 4, 2016

I have issue with the following code (reduced for be simpliest as possible).
I'm want to unsubcribe from an observable coming from a subject.
I'm unsubcribed, but the lambda is kept somewhere...

#include <rxcpp/rx.hpp>
#include <memory>

int main(int argc, char *argv[]) {
 {
   ::rxcpp::subjects::subject<int> subject;
   auto s = subject.get_subscriber();
          s.on_next(1);
            s.on_next(2);
   auto ints = subject.get_observable();

 class String {
   private:
   std::string mS;
public:
   String(const std::string &s): mS(s) {
    std::cout << "Create" << std::endl;
   };
   ~String() {
    std::cout << "Destroy" << std::endl;
   }
   const std::string & getStr() const {
     return mS;
   }
 };

 rxcpp::subscription sub;
 {
  std::shared_ptr<String> str = std::make_shared<String>(std::string("Test"));
  sub = ints.subscribe(
        [=](int v) {
     std::cout << str->getStr() << std::endl;
    });
  }
  std::cout << "PU" << std::endl;
  sub.unsubscribe();
  std::cout << "AU" << std::endl;
}
  std::cout << "destroy subject" << std::endl;

 return 0;
}

I was expecting

Create
PU
Destroy
AU
destroy subject

but i have:

Create
PU
AU
Destroy
destroy subject

Is it normal?

@diorcety
Copy link
Contributor Author

diorcety commented Aug 5, 2016

Seems to be a bug.
Change

std::cout << "PU" << std::endl;
sub.unsubscribe();
std::cout << "AU" << std::endl;

by

std::cout << "PU" << std::endl;
sub.unsubscribe();
ints.subscribe([=](int v) {});
std::cout << "AU" << std::endl;

Something miss here https://github.com/Reactive-Extensions/RxCpp/blob/master/Rx/v2/src/rxcpp/subjects/rx-subject.hpp#L67 in order to remove from the vector on unsubscription

Using ints.subscribe([=](int v) {}); truck allow to rework the observers vector an remove my old subscription.

@diorcety
Copy link
Contributor Author

diorcety commented Aug 5, 2016

Juste after the L67 seems to almost work (but certainly ugly) :)

        o.add([=](){
          this->observers.erase(std::remove_if(observers.begin(), observers.end(), [&](auto l){
             return l.get_id() == o.get_id();
          }), observers.end());
        });

@kirkshoop
Copy link
Member

There are issues with circular lifetimes and locks that need to be addressed.

I think I was able to fix this in #243.

Thank you for the report and diagnosis! This was very helpful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants