diff options
author | Tim Moore <timoore@redhat.com> | 2009-12-09 22:09:39 +0100 |
---|---|---|
committer | Tim Moore <timoore@redhat.com> | 2009-12-09 22:09:39 +0100 |
commit | 3e1613e1f7ab589089e8ed5a504330bb9cb128db (patch) | |
tree | cc2a639738801467b52dad823d2eb4e2b187bf4e /grapher/grapher.cxx | |
parent | f4ba7c13533b7e99edd0e66a0f6ccd6c0f55ec38 (diff) | |
download | systemtap-steved-3e1613e1f7ab589089e8ed5a504330bb9cb128db.tar.gz systemtap-steved-3e1613e1f7ab589089e8ed5a504330bb9cb128db.tar.xz systemtap-steved-3e1613e1f7ab589089e8ed5a504330bb9cb128db.zip |
show the status of stap processes in the process window
Also, the "kill" button now works.
* grapher/StapParser.hxx (_ioConnection, _errIoConnection): new
members for sigc connections.
(initIo): New function
(parsers, parserListChangedSignal): new variables
* grapher/StapParser.cxx (ioCallback): disconnect signals when child
dies
(initIo): new function
* grapher/grapher.cxx (StapLauncher): eliminate death callback in
favor of childDied signal. Use global parsers list
(ProcWindow::_listSelection): new member
(ProcWindow::show, hide, onParserListChanged, onSelectionChanged,
onKill): new functions
(ProcWindow::ProcWindow): Set up cell renderer for status icon
* grapher/processwindow.glade: labels for display script and stap arguments
Diffstat (limited to 'grapher/grapher.cxx')
-rw-r--r-- | grapher/grapher.cxx | 167 |
1 files changed, 113 insertions, 54 deletions
diff --git a/grapher/grapher.cxx b/grapher/grapher.cxx index 2a9a617b..00670fe0 100644 --- a/grapher/grapher.cxx +++ b/grapher/grapher.cxx @@ -106,14 +106,14 @@ private: class StapLauncher : public ChildDeathReader { public: - StapLauncher() : _argv(0), _childPid(-1), _deathCallback(0) {} + StapLauncher() : _argv(0), _childPid(-1) {} StapLauncher(char** argv) - : _argv(argv), _childPid(-1), _deathCallback(0) + : _argv(argv), _childPid(-1) { } StapLauncher(const string& stapArgs, const string& script, const string& scriptArgs) - : _childPid(-1), _deathCallback(0), _win(0), _widget(0) + : _childPid(-1), _win(0), _widget(0) { setArgs(stapArgs, script, scriptArgs); } @@ -149,10 +149,7 @@ public: _script.clear(); _scriptArgs.clear(); } - void setDeathCallback(ChildDeathReader::Callback* callback) - { - _deathCallback = callback; - } + void setWinParams(Gtk::Window* win, GraphWidget* widget) { _win = win; @@ -163,7 +160,8 @@ public: shared_ptr<StapParser> makeStapParser() { shared_ptr<StapParser> result(new StapParser); - _parsers.push_back(result); + parsers.push_back(result); + parserListChangedSignal().emit(); return result; } private: @@ -184,14 +182,22 @@ public: if (pid < 0) return pid; ParserList::iterator itr - = find_if(_parsers.begin(), _parsers.end(), pidPred(pid)); - if (itr != _parsers.end()) - (*itr)->setProcess(tr1::shared_ptr<StapProcess>()); + = find_if(parsers.begin(), parsers.end(), pidPred(pid)); + if (itr != parsers.end()) + { + tr1::shared_ptr<StapProcess> sp = (*itr)->getProcess(); + if (sp) + { + sp->pid = -1; + parserListChangedSignal().emit(); + } + } + childDiedSignal().emit(pid); return pid; } void killAll() { - for (ParserList::iterator itr = _parsers.begin(), end = _parsers.end(); + for (ParserList::iterator itr = parsers.begin(), end = parsers.end(); itr != end; ++itr) { @@ -199,15 +205,12 @@ public: kill((*itr)->getPid(), SIGTERM); } } - typedef vector<shared_ptr<StapParser> > ParserList; - ParserList _parsers; protected: char** _argv; string _stapArgs; string _script; string _scriptArgs; int _childPid; - ChildDeathReader::Callback* _deathCallback; Gtk::Window* _win; GraphWidget* _widget; }; @@ -287,17 +290,9 @@ int StapLauncher::launch() proc->scriptArgs = _scriptArgs; } sp->setProcess(proc); - _parsers.push_back(sp); - sp->setErrFd(pipefd[2]); - sp->setInFd(pipefd[0]); - Glib::signal_io().connect(sigc::mem_fun(sp.get(), - &StapParser::errIoCallback), - pipefd[2], - Glib::IO_IN); - Glib::signal_io().connect(sigc::mem_fun(sp.get(), - &StapParser::ioCallback), - pipefd[0], - Glib::IO_IN | Glib::IO_HUP); + parsers.push_back(sp); + parserListChangedSignal().emit(); + sp->initIo(pipefd[0], pipefd[2]); return childPid; } @@ -313,7 +308,7 @@ void StapLauncher::cleanUp() char buf; while (read(signalPipe[0], &buf, 1) > 0) reap(); - for (ParserList::iterator itr = _parsers.begin(), end = _parsers.end(); + for (ParserList::iterator itr = parsers.begin(), end = parsers.end(); itr != end; ++itr) { @@ -331,8 +326,10 @@ void StapLauncher::cleanUp() std::cerr << "wait: killed Pid " << killedPid << " != child Pid " << childPid << "\n"; } - else if (_deathCallback) - _deathCallback->childDied(childPid); + else + { + childDiedSignal().emit(childPid); + } } } @@ -356,13 +353,16 @@ class ProcModelColumns : public Gtk::TreeModelColumnRecord public: ProcModelColumns() { + add(_iconName); add(_scriptName); add(_proc); } + Gtk::TreeModelColumn<Glib::ustring> _iconName; Gtk::TreeModelColumn<Glib::ustring> _scriptName; Gtk::TreeModelColumn<shared_ptr<StapProcess> > _proc; }; +// This should probably be a Gtk window, with the appropriate glade magic class ProcWindow { public: @@ -372,10 +372,20 @@ public: Gtk::Window* _window; Gtk::TreeView* _dataTreeView; Glib::RefPtr<Gtk::ListStore> _listStore; + Glib::RefPtr<Gtk::TreeSelection> _listSelection; void onClose(); + void show(); + void hide(); + void onParserListChanged(); + void onSelectionChanged(); + void onKill(); +private: + bool _open; + void refresh(); }; ProcWindow::ProcWindow() + : _open(false) { try { @@ -390,12 +400,27 @@ ProcWindow::ProcWindow() throw; } _listStore = Gtk::ListStore::create(_modelColumns); - _dataTreeView->set_model(_listStore); + _dataTreeView->set_model(_listStore); + // Display a nice icon for the state of the process + Gtk::CellRendererPixbuf* cell = Gtk::manage(new Gtk::CellRendererPixbuf); + _dataTreeView->append_column("State", *cell); + Gtk::TreeViewColumn* column = _dataTreeView->get_column(0); + if (column) + column->add_attribute(cell->property_icon_name(), _modelColumns._iconName); _dataTreeView->append_column("Script", _modelColumns._scriptName); Gtk::Button* button = 0; _xml->get_widget("button5", button); button->signal_clicked().connect(sigc::mem_fun(*this, &ProcWindow::onClose), false); + _xml->get_widget("button1", button); + button->signal_clicked().connect(sigc::mem_fun(*this, &ProcWindow::onKill), + false); + parserListChangedSignal() + .connect(sigc::mem_fun(*this, &ProcWindow::onParserListChanged)); + _listSelection = _dataTreeView->get_selection(); + _listSelection->signal_changed() + .connect(sigc::mem_fun(*this, &ProcWindow::onSelectionChanged)); + } void ProcWindow::onClose() @@ -403,6 +428,63 @@ void ProcWindow::onClose() _window->hide(); } +void ProcWindow::show() +{ + _open = true; + refresh(); + _window->show(); + +} + +void ProcWindow::hide() +{ + _open = false; + _window->hide(); +} + +void ProcWindow::refresh() +{ + _listStore->clear(); + for (ParserList::iterator spitr = parsers.begin(), end = parsers.end(); + spitr != end; + ++spitr) + { + shared_ptr<StapProcess> sp = (*spitr)->getProcess(); + if (sp) + { + Gtk::TreeModel::iterator litr = _listStore->append(); + Gtk::TreeModel::Row row = *litr; + row[_modelColumns._iconName] = sp->pid >= 0 ? "gtk-yes" : "gtk-no"; + row[_modelColumns._scriptName] = sp->script; + row[_modelColumns._proc] = sp; + } + } +} + +void ProcWindow::onParserListChanged() +{ + if (_open) + { + refresh(); + _window->queue_draw(); + } +} + +void ProcWindow::onSelectionChanged() +{ +} + +void ProcWindow::onKill() +{ + Gtk::TreeModel::iterator itr = _listSelection->get_selected(); + if (!itr) + return; + Gtk::TreeModel::Row row = *itr; + shared_ptr<StapProcess> proc = row[_modelColumns._proc]; + if (proc->pid >= 0) + kill(proc->pid, SIGTERM); +} + class GrapherWindow : public Gtk::Window, public ChildDeathReader::Callback { public: @@ -411,7 +493,6 @@ public: Gtk::VBox m_Box; Gtk::ScrolledWindow scrolled; GraphWidget w; - void childDied(int pid); void setGraphicalLauncher(GraphicalStapLauncher* launcher) { _graphicalLauncher = launcher; @@ -505,30 +586,9 @@ void GrapherWindow::on_menu_script_start() void GrapherWindow::on_menu_proc_window() { - _procWindow->_listStore->clear(); - for (StapLauncher::ParserList::iterator spitr - = _graphicalLauncher->_parsers.begin(), - end = _graphicalLauncher->_parsers.end(); - spitr != end; - ++spitr) - { - shared_ptr<StapProcess> sp = (*spitr)->getProcess(); - Gtk::TreeModel::iterator litr = _procWindow->_listStore->append(); - Gtk::TreeModel::Row row = *litr; - if (sp) - row[_procWindow->_modelColumns._scriptName] = sp->script; - } - _procWindow->_window->show(); + _procWindow->show(); } -void GrapherWindow::childDied(int pid) -{ - hide(); -} - - - - int main(int argc, char** argv) { Gtk::Main app(argc, argv); @@ -553,7 +613,6 @@ int main(int argc, char** argv) else if (argc > 1) { launcher.setArgv(argv + 1); - launcher.setDeathCallback(&win); launcher.launch(); } Gtk::Main::run(win); |