# # # patch "misc.cc" # from [ab49f55cea21542d5152a10dc79ae889f1de621c] # to [10644b4af7fe457dfbd3ab487743e90986d16411] # # patch "misc.hh" # from [6097ccba66ffcf581f1bacdd41bddb43d9f138fc] # to [6d7f5031038c1712650c75736ea0ed71d2a2116e] # # patch "monotone.cc" # from [8c9617d68b515df99769b27e2826cef8b063b811] # to [89803f1e9cd7fe3af6585aa7cafc8141d9a6d874] # # patch "monotone.hh" # from [06e3ddf2b1a6c3ef240bed07fd71e19a7989f3ea] # to [a756cb937ea04ab9861c1299e9369c0a017960e8] # ============================================================ --- misc.cc ab49f55cea21542d5152a10dc79ae889f1de621c +++ misc.cc 10644b4af7fe457dfbd3ab487743e90986d16411 @@ -74,16 +74,23 @@ } // Run the event loop while waiting for monotone to finish. -void ProgressDialog::do_wait() +void ProgressDialog::do_wait(string & fin) { while (mtn->is_busy()) { - Gtk::Main::iteration(); + for (int i = 0; i < 100 && mtn->is_busy() + && Gtk::Main::events_pending(); ++i) + Gtk::Main::iteration(); string & str(mtn->output_err); + if (str.size() == 0) + continue; + + // This gets rid of lines hidden by \r . int r = str.rfind("\r"); int n = str.rfind("\n", r); if (r != string::npos && n != string::npos) str = str.substr(0, n+1) + str.substr(r+1); + Glib::RefPtr b = tv.get_buffer(); b->set_text(str); Glib::RefPtr t = b->create_tag(); @@ -94,15 +101,18 @@ void SyncDialog::callmtn() { + std::cerr<<"frob\n"; mtn->sync(); - do_wait(); + std::cerr<<"friz\n"; + do_wait(output); + std::cerr<<"franz\n"; } void UpdateDialog::callmtn() { std::vector rr; mtn->update(rr, output); - do_wait(); + do_wait(output); if (!rr.empty()) { chooser c(rr); @@ -113,7 +123,7 @@ if (!rev.empty()) { mtn->update(rev, output); - do_wait(); + do_wait(output); } } } ============================================================ --- misc.hh 6097ccba66ffcf581f1bacdd41bddb43d9f138fc +++ misc.hh 6d7f5031038c1712650c75736ea0ed71d2a2116e @@ -38,7 +38,7 @@ ~ProgressDialog(); bool timer(); virtual void callmtn() {} - void do_wait(); + void do_wait(string & fin); }; struct SyncDialog : public ProgressDialog ============================================================ --- monotone.cc 8c9617d68b515df99769b27e2826cef8b063b811 +++ monotone.cc 89803f1e9cd7fe3af6585aa7cafc8141d9a6d874 @@ -25,7 +25,7 @@ inline int max(int a, int b) {return (a>b)?a:b;} -monotone::monotone(): pid(0), dir(".") +monotone::monotone(): pid(0), dir("."), done(2) { } @@ -59,16 +59,18 @@ bool monotone::got_data(Glib::IOCondition c, Glib::RefPtr chan) { - if (c != Glib::IO_IN) + if (c == Glib::IO_HUP) { - std::cerr<<"&"; - busy = false; + if (++done == 2) + (std::cerr<<"&"), child_exited(0, 0); + else + std::cerr<<"%"<read(data, 1040); - gunichar data; - chan->read(data); + Glib::ustring data; + chan->read(data, 1040); +// gunichar data; +// chan->read(data); if (mode == STDIO) { tempstr += data; @@ -88,31 +90,37 @@ bool monotone::got_err(Glib::IOCondition c, Glib::RefPtr chan) { - if (c != Glib::IO_IN) + if (c == Glib::IO_HUP) { - std::cerr<<"*"; - busy = false; + std::cerr<read(data, 1040); - gunichar data; - chan->read(data); + Glib::ustring data; + chan->read(data, 1040); +// gunichar data; +// chan->read(data); output_err += data; return true; } void monotone::setup_callbacks() { + done = 0; { Glib::RefPtr ioc = Glib::IOChannel::create_from_fd(from); - Glib::RefPtr ios = Glib::IOSource::create(ioc, Glib::IO_IN); + ioc->set_flags(Glib::IO_FLAG_NONBLOCK); + Glib::RefPtr ios = Glib::IOSource::create(ioc, Glib::IO_IN | Glib::IO_HUP); ios->connect(sigc::bind(sigc::mem_fun(*this, &monotone::got_data), ioc)); ios->attach(Glib::MainContext::get_default()); } { Glib::RefPtr ioc = Glib::IOChannel::create_from_fd(errfrom); - Glib::RefPtr ios = Glib::IOSource::create(ioc, Glib::IO_IN); + ioc->set_flags(Glib::IO_FLAG_NONBLOCK); + Glib::RefPtr ios = Glib::IOSource::create(ioc, Glib::IO_IN | Glib::IO_HUP); ios->connect(sigc::bind(sigc::mem_fun(*this, &monotone::got_err), ioc)); ios->attach(Glib::MainContext::get_default()); } @@ -120,7 +128,13 @@ bool monotone::execute(vector args) -{std::cerr<<"spawn()\n"; +{ + if (done < 2) + { + std::cerr<<"Not spawning, pipes still open!\n"; + return false; + } + std::cerr<<"spawn()\n"; args.insert(args.begin(), Glib::find_program_in_path("monotone")); if (!db.empty()) args.push_back("--db=" + db); @@ -142,10 +156,10 @@ void monotone::child_exited(Glib::Pid p, int c) { - pid = 0; - std::cerr<<"exited.\n"; + std::cerr<<"cleanup...\n"; + stopped(); signal_done.emit(); - busy = false; + busy = false;std::cerr<<"no longer busy\n"; signal_done.clear(); output_std.clear(); output_err.clear(); @@ -155,6 +169,7 @@ monotone::start() { stop(); + while (done < 2) Gtk::Main::iteration(); mode = STDIO; std::vector args; args.push_back("automate"); @@ -167,8 +182,7 @@ if (!pid) { std::cerr<<"Already stopped.\n"; - if (busy) std::cerr<<"\tBut somehow still busy!\n"; - busy = false; + if (busy) std::cerr<<"\tBut still busy!\n"; return false; } std::cerr<<"kill()\n"; @@ -181,7 +195,6 @@ #endif Glib::spawn_close_pid(pid); pid = 0; - busy = false; return true; } @@ -204,6 +217,14 @@ return true; } +bool +monotone::is_busy() +{ +// if (busy && stopped()) +// child_exited(0, 0); + return busy; +} + void monotone::waitfor() { @@ -240,11 +261,12 @@ vector const & args) { stop();// stop stdio - busy = true; + while (done < 2) Gtk::Main::iteration(); mode = EXEC; std::vector argg = args; argg.insert(argg.begin(), cmd); execute(argg); + busy = true; } namespace { ============================================================ --- monotone.hh 06e3ddf2b1a6c3ef240bed07fd71e19a7989f3ea +++ monotone.hh a756cb937ea04ab9861c1299e9369c0a017960e8 @@ -63,6 +63,7 @@ string tempstr; sigc::signal signal_done; + int done; public: string output_std, output_err; @@ -78,7 +79,7 @@ void waitfor(); // call this when the current command finished void when_done(sigc::slot cb); - bool is_busy() {return busy;} + bool is_busy(); // run a command with 'automate stdio' void command(string const & cmd, vector const & args);