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

Leaves 5 processes running after stop #55

Open
philn opened this issue Oct 24, 2022 · 7 comments
Open

Leaves 5 processes running after stop #55

philn opened this issue Oct 24, 2022 · 7 comments

Comments

@philn
Copy link
Contributor

philn commented Oct 24, 2022

The "UI" thread is at least one process. The 4 others I'm not sure yet what they're for. Stopping a source element should clean-up resources, it's currently not the case, until the app process is terminated.

@philn
Copy link
Contributor Author

philn commented Oct 24, 2022

Test case:

use gst::prelude::*;
use gstreamer as gst;
use sysinfo::{ProcessExt, System, SystemExt};

fn create_pipeline() -> gst::Pipeline {
    let pipeline = gst::Pipeline::new(None);
    let src = gst::ElementFactory::make("cefsrc", None).unwrap();
    src.set_property(
        "url",
        &"https://webkit.org/blog-files/3d-transforms/poster-circle.html",
    );
    src.set_property("num-buffers", &100);
    let convert = gst::ElementFactory::make("videoconvert", None).unwrap();
    let queue = gst::ElementFactory::make("queue", None).unwrap();
    let sink = gst::ElementFactory::make("fakevideosink", None).unwrap();

    pipeline.add_many(&[&src, &convert, &queue, &sink]).unwrap();
    gst::Element::link_many(&[&src, &convert, &queue, &sink]).unwrap();
    pipeline.set_state(gst::State::Playing).unwrap();
    pipeline
}

fn run() {
    let mut sys = System::new_all();
    for i in 0..2 {
        println!("Creating pipeline #{}", i);
        let pipeline = create_pipeline();
        let bus = pipeline.bus().unwrap();
        for msg in bus.iter_timed(gst::ClockTime::NONE) {
            if let gst::MessageView::Eos(..) = msg.view() {
                break;
            }
        }

        bus.unset_sync_handler();
        println!("Destroying pipeline");
        pipeline.set_state(gst::State::Null).unwrap();

        drop(pipeline);
        sys.refresh_all();
        let mut total = 0;
        for (pid, process) in sys.processes() {
            let name = process.name();
            if name.starts_with("gstcefsub") {
                println!("[{}] {} {:?}", pid, &name, process.disk_usage());
                total += 1;
            }
        }
        println!("Total CEF processes: {}", total);
    }
}

fn main() {
    gst::init().unwrap();
    run();
    unsafe {
        gstreamer::deinit();
    }
}

@philn
Copy link
Contributor Author

philn commented Oct 24, 2022

I wonder about reverting e2da7ea and spinning a GMainLoop in a new thread, tied to the src element.

@MathieuDuponchelle
Copy link
Collaborator

I get your point, but I'm afraid you can't simply revert that commit, prior to it the situation was really not optimal, and you could only really have one cefsrc per process, which is arguably worse than failure to clean things up :P Still as mentioned here: e2da7ea#diff-b511dd6555eaa8cc62167e0332cbbda8f626ad7900fa3a9b092292a6c07e1ac5R326 mentions we could refine the new approach to stop and restart the UI thread as needed, I would suggest digging in that direction :) Did you find out what those 4 other processes are, and what CEF calls would get us rid of them? :)

@philn
Copy link
Contributor Author

philn commented Oct 25, 2022

we could refine the new approach to stop and restart the UI thread as needed, I would suggest digging in that direction :)

I tried that already kindof, but then the second time CefInitialize() is called, the process crashes deep in the chromium...

Did you find out what those 4 other processes are, and what CEF calls would get us rid of them? :)

Not yet... only hint so far that I've found is that people just kill those processess using usual OS syscalls...

@MathieuDuponchelle
Copy link
Collaborator

Crashes deep into chromium I'm afraid I will be little help with, however I'm curious, what happens if you only call CefQuitMessageLoop() (and not CefShutdown, which I believe is the pendant to CefInitialize)?

@philn
Copy link
Contributor Author

philn commented Oct 25, 2022

Yes I tried moving the UI thread to element scope, not calling CefShutdown either, but then on second run the MakeBrowser task is not dispatched to the new UI thread... I suspect some global state in CEF is left dangling after the first UI thread was stopped and that messes up everything on subsequent runs...

@MathieuDuponchelle
Copy link
Collaborator

Hm, I see, I'm afraid I don't have too many pointers here but I'll happily review and merge something if you find a solution, just please bear in mind that prior to the patch you mentioned it was not possible to run multiple cefsrc instances concurrently in the same process, and we should try not to regress on that :)

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