diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index cc8b592c..8fdbc22c 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -5,6 +5,8 @@ on: push: paths-ignore: - "**.md" + branches: + - feature/fix-memoryleak3 schedule: # UTC の 01:00 は JST だと 10:00 。 # 1-5 で 月曜日から金曜日 @@ -31,6 +33,7 @@ jobs: contains(github.event.head_commit.message, '[e2e]') || contains(github.ref, 'feature/e2e-test') || github.event_name == 'workflow_dispatch' || + github.event_name == 'push' || github.event_name == 'schedule' }} steps: @@ -73,6 +76,7 @@ jobs: contains(github.event.head_commit.message, '[e2e]') || contains(github.ref, 'feature/e2e-test') || github.event_name == 'workflow_dispatch' || + github.event_name == 'push' || github.event_name == 'schedule' }} steps: @@ -106,6 +110,7 @@ jobs: contains(github.event.head_commit.message, '[e2e]') || contains(github.ref, 'feature/e2e-test') || github.event_name == 'workflow_dispatch' || + github.event_name == 'push' || github.event_name == 'schedule' }} steps: diff --git a/src/sora.cpp b/src/sora.cpp index 44c284b8..281756bb 100644 --- a/src/sora.cpp +++ b/src/sora.cpp @@ -61,7 +61,8 @@ std::shared_ptr Sora::CreateConnection( std::optional proxy_password, std::optional proxy_agent, std::optional degradation_preference) { - std::shared_ptr conn = std::make_shared(this); + std::shared_ptr conn = + std::make_shared(this, factory_); sora::SoraSignalingConfig config; config.pc_factory = factory_->GetPeerConnectionFactory(); config.observer = conn; @@ -213,13 +214,6 @@ std::shared_ptr Sora::CreateConnection( conn->SetVideoSenderFrameTransformer(video_frame_transformer); } - weak_connections_.erase( - std::remove_if( - weak_connections_.begin(), weak_connections_.end(), - [](std::weak_ptr w) { return w.expired(); }), - weak_connections_.end()); - weak_connections_.push_back(conn); - return conn; } diff --git a/src/sora.h b/src/sora.h index 4ab448bd..fff4bc57 100644 --- a/src/sora.h +++ b/src/sora.h @@ -161,8 +161,6 @@ class Sora : public DisposePublisher { */ SoraVideoSource* CreateVideoSource(); - std::vector> weak_connections_; - private: /** * Python で渡された値を boost::json::value に変換します。 @@ -186,6 +184,6 @@ class Sora : public DisposePublisher { std::optional ConvertForwardingFilter(const nb::handle value); - std::unique_ptr factory_; + std::shared_ptr factory_; }; #endif diff --git a/src/sora_connection.cpp b/src/sora_connection.cpp index 61f12fd6..759e059d 100644 --- a/src/sora_connection.cpp +++ b/src/sora_connection.cpp @@ -20,8 +20,9 @@ namespace nb = nanobind; -SoraConnection::SoraConnection(DisposePublisher* publisher) - : publisher_(publisher) { +SoraConnection::SoraConnection(DisposePublisher* publisher, + std::shared_ptr factory) + : publisher_(publisher), factory_(factory) { publisher_->AddSubscriber(this); } @@ -30,6 +31,8 @@ SoraConnection::~SoraConnection() { publisher_->RemoveSubscriber(this); } Disposed(); + conn_ = nullptr; + factory_ = nullptr; } void SoraConnection::Disposed() { diff --git a/src/sora_connection.h b/src/sora_connection.h index c53be2be..c81bba7a 100644 --- a/src/sora_connection.h +++ b/src/sora_connection.h @@ -24,6 +24,7 @@ namespace nb = nanobind; +class SoraFactory; /** * Sora との接続ごとに生成する SoraConnection です。 * @@ -36,7 +37,8 @@ class SoraConnection : public sora::SoraSignalingObserver, /** * コンストラクタではインスタンスの生成のみで実際の生成処理は Init 関数で行います。 */ - SoraConnection(DisposePublisher* publisher); + SoraConnection(DisposePublisher* publisher, + std::shared_ptr factory); ~SoraConnection(); void Disposed() override; @@ -146,6 +148,7 @@ class SoraConnection : public sora::SoraSignalingObserver, std::function on_data_channel_; private: + std::shared_ptr factory_; DisposePublisher* publisher_; std::unique_ptr ioc_; std::shared_ptr conn_; diff --git a/src/sora_sdk_ext.cpp b/src/sora_sdk_ext.cpp index 84c48d11..e1981496 100644 --- a/src/sora_sdk_ext.cpp +++ b/src/sora_sdk_ext.cpp @@ -288,38 +288,6 @@ PyType_Slot connection_slots[] = { {Py_tp_clear, (void*)connection_tp_clear}, {0, nullptr}}; -int sora_tp_traverse(PyObject* self, visitproc visit, void* arg) { - if (!nb::inst_ready(self)) { - return 0; - } - - Sora* sora = nb::inst_ptr(self); - for (auto wc : sora->weak_connections_) { - auto conn = wc.lock(); - if (conn) { - nb::object conn_obj = nb::find(conn); - Py_VISIT(conn_obj.ptr()); - } - } - - return 0; -} - -int sora_tp_clear(PyObject* self) { - if (!nb::inst_ready(self)) { - return 0; - } - - Sora* sora = nb::inst_ptr(self); - sora->weak_connections_.clear(); - - return 0; -} - -PyType_Slot sora_slots[] = {{Py_tp_traverse, (void*)sora_tp_traverse}, - {Py_tp_clear, (void*)sora_tp_clear}, - {0, nullptr}}; - /** * Python で利用するすべてのクラスと定数は以下のように定義しなければならない */ @@ -568,7 +536,7 @@ NB_MODULE(sora_sdk_ext, m) { .def("__del__", &SoraVideoFrameTransformer::Del) .def_rw("on_transform", &SoraVideoFrameTransformer::on_transform_); - nb::class_(m, "Sora", nb::type_slots(sora_slots)) + nb::class_(m, "Sora") .def(nb::init, std::optional>(), "use_hardware_encoder"_a = nb::none(), "openh264"_a = nb::none()) .def("create_connection", &Sora::CreateConnection, "signaling_urls"_a, diff --git a/src/sora_video_source.cpp b/src/sora_video_source.cpp index e03eb594..fc61db86 100644 --- a/src/sora_video_source.cpp +++ b/src/sora_video_source.cpp @@ -20,6 +20,10 @@ SoraVideoSource::SoraVideoSource( })); } +SoraVideoSource::~SoraVideoSource() { + Disposed(); +} + void SoraVideoSource::Disposed() { if (!finished_) { finished_ = true; diff --git a/src/sora_video_source.h b/src/sora_video_source.h index cbc843fb..61704865 100644 --- a/src/sora_video_source.h +++ b/src/sora_video_source.h @@ -35,6 +35,7 @@ class SoraVideoSource : public SoraTrackInterface { SoraVideoSource(DisposePublisher* publisher, rtc::scoped_refptr source, rtc::scoped_refptr track); + ~SoraVideoSource(); void Disposed() override; void PublisherDisposed() override;