app list is now managable from gladish

This commit is contained in:
Nedko Arnaudov 2009-12-04 21:37:39 +02:00
parent 38a0bc211a
commit 89461c363c
6 changed files with 214 additions and 28 deletions

View File

@ -42,6 +42,7 @@ struct ladish_app
bool terminal;
uint8_t level;
pid_t pid;
bool zombie;
};
struct ladish_app_supervisor
@ -125,6 +126,45 @@ struct ladish_app * ladish_app_supervisor_find_app_by_id(struct ladish_app_super
return NULL;
}
void remove_app_internal(struct ladish_app_supervisor * supervisor_ptr, struct ladish_app * app_ptr)
{
list_del(&app_ptr->siblings);
dbus_signal_emit(
g_dbus_connection,
supervisor_ptr->opath,
IFACE_APP_SUPERVISOR,
"AppRemoved",
"tt",
&supervisor_ptr->version,
&app_ptr->id);
free(app_ptr->name);
free(app_ptr->commandline);
free(app_ptr);
}
void emit_app_state_changed(struct ladish_app_supervisor * supervisor_ptr, struct ladish_app * app_ptr)
{
dbus_bool_t running;
dbus_bool_t terminal;
running = app_ptr->pid != 0;
terminal = app_ptr->terminal;
dbus_signal_emit(
g_dbus_connection,
supervisor_ptr->opath,
IFACE_APP_SUPERVISOR,
"AppStateChanged",
"tsbby",
&app_ptr->id,
&app_ptr->name,
&running,
&terminal,
&app_ptr->level);
}
#define supervisor_ptr ((struct ladish_app_supervisor *)supervisor_handle)
void ladish_app_supervisor_destroy(ladish_app_supervisor_handle supervisor_handle)
@ -134,10 +174,7 @@ void ladish_app_supervisor_destroy(ladish_app_supervisor_handle supervisor_handl
while (!list_empty(&supervisor_ptr->applist))
{
app_ptr = list_entry(supervisor_ptr->applist.next, struct ladish_app, siblings);
list_del(&app_ptr->siblings);
free(app_ptr->name);
free(app_ptr->commandline);
free(app_ptr);
remove_app_internal(supervisor_ptr, app_ptr);
}
free(supervisor_ptr->name);
@ -157,20 +194,16 @@ bool ladish_app_supervisor_child_exit(ladish_app_supervisor_handle supervisor_ha
{
log_info("exit of studio child '%s' detected.", app_ptr->name);
list_del(&app_ptr->siblings);
app_ptr->pid = 0;
if (app_ptr->zombie)
{
remove_app_internal(supervisor_ptr, app_ptr);
}
else
{
emit_app_state_changed(supervisor_ptr, app_ptr);
}
dbus_signal_emit(
g_dbus_connection,
supervisor_ptr->opath,
IFACE_APP_SUPERVISOR,
"AppRemoved",
"tt",
&supervisor_ptr->version,
&app_ptr->id);
free(app_ptr->name);
free(app_ptr->commandline);
free(app_ptr);
return true;
}
}
@ -356,6 +389,7 @@ static void run_custom(struct dbus_method_call * call_ptr)
app_ptr->id = supervisor_ptr->next_id++;
app_ptr->name = name;
app_ptr->commandline = strdup(commandline);
app_ptr->terminal = terminal;
app_ptr->pid = 0;
if (app_ptr->commandline == NULL)
{
@ -365,6 +399,7 @@ static void run_custom(struct dbus_method_call * call_ptr)
return;
}
app_ptr->zombie = false;
list_add_tail(&app_ptr->siblings, &supervisor_ptr->applist);
if (!loader_execute(supervisor_ptr->name, name, "/", terminal, commandline, &app_ptr->pid))
@ -427,12 +462,14 @@ static void start_app(struct dbus_method_call * call_ptr)
return;
}
app_ptr->zombie = false;
if (!loader_execute(supervisor_ptr->name, app_ptr->name, "/", app_ptr->terminal, app_ptr->commandline, &app_ptr->pid))
{
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "Execution of '%s' failed", app_ptr->commandline);
return;
}
emit_app_state_changed(supervisor_ptr, app_ptr);
log_info("%s pid is %lu", app_ptr->name, (unsigned long)app_ptr->pid);
method_return_new_void(call_ptr);
@ -516,6 +553,38 @@ static void set_app_properties(struct dbus_method_call * call_ptr)
static void remove_app(struct dbus_method_call * call_ptr)
{
uint64_t id;
struct ladish_app * app_ptr;
if (!dbus_message_get_args(
call_ptr->message,
&g_dbus_error,
DBUS_TYPE_UINT64, &id,
DBUS_TYPE_INVALID))
{
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "Invalid arguments to method \"%s\": %s", call_ptr->method_name, g_dbus_error.message);
dbus_error_free(&g_dbus_error);
return;
}
app_ptr = ladish_app_supervisor_find_app_by_id(supervisor_ptr, id);
if (app_ptr == NULL)
{
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "App with ID %"PRIu64" not found", id);
return;
}
if (app_ptr->pid != 0)
{
app_ptr->zombie = true;
kill(app_ptr->pid, SIGTERM);
}
else
{
remove_app_internal(supervisor_ptr, app_ptr);
}
method_return_new_void(call_ptr);
}
static void is_app_running(struct dbus_method_call * call_ptr)
@ -573,6 +642,10 @@ METHOD_ARGS_BEGIN(KillApp, "Kill application")
METHOD_ARG_DESCRIBE_IN("id", DBUS_TYPE_UINT64_AS_STRING, "id of app")
METHOD_ARGS_END
METHOD_ARGS_BEGIN(RemoveApp, "Remove application")
METHOD_ARG_DESCRIBE_IN("id", DBUS_TYPE_UINT64_AS_STRING, "id of app")
METHOD_ARGS_END
METHOD_ARGS_BEGIN(GetAppProperties, "Get properties of an application")
METHOD_ARG_DESCRIBE_IN("id", DBUS_TYPE_UINT64_AS_STRING, "id of app")
METHOD_ARG_DESCRIBE_OUT("name", DBUS_TYPE_STRING_AS_STRING, "")
@ -603,7 +676,7 @@ METHODS_BEGIN
METHOD_DESCRIBE(KillApp, kill_app)
METHOD_DESCRIBE(GetAppProperties, get_app_properties)
METHOD_DESCRIBE(SetAppProperties, set_app_properties)
METHOD_DESCRIBE(KillApp, remove_app)
METHOD_DESCRIBE(RemoveApp, remove_app)
METHOD_DESCRIBE(IsAppRunning, is_app_running)
METHODS_END

View File

@ -316,4 +316,48 @@ bool ladish_app_supervisor_proxy_run_custom(ladish_app_supervisor_proxy_handle p
return true;
}
bool ladish_app_supervisor_proxy_start_app(ladish_app_supervisor_proxy_handle proxy, uint64_t id)
{
if (!dbus_call(proxy_ptr->service, proxy_ptr->object, IFACE_APP_SUPERVISOR, "StartApp", "t", &id, ""))
{
log_error("StartApp() failed.");
return false;
}
return true;
}
bool ladish_app_supervisor_proxy_stop_app(ladish_app_supervisor_proxy_handle proxy, uint64_t id)
{
if (!dbus_call(proxy_ptr->service, proxy_ptr->object, IFACE_APP_SUPERVISOR, "StopApp", "t", &id, ""))
{
log_error("StopApp() failed.");
return false;
}
return true;
}
bool ladish_app_supervisor_proxy_kill_app(ladish_app_supervisor_proxy_handle proxy, uint64_t id)
{
if (!dbus_call(proxy_ptr->service, proxy_ptr->object, IFACE_APP_SUPERVISOR, "KillApp", "t", &id, ""))
{
log_error("KillApp() failed.");
return false;
}
return true;
}
bool ladish_app_supervisor_proxy_remove_app(ladish_app_supervisor_proxy_handle proxy, uint64_t id)
{
if (!dbus_call(proxy_ptr->service, proxy_ptr->object, IFACE_APP_SUPERVISOR, "RemoveApp", "t", &id, ""))
{
log_error("RemoveApp() failed.");
return false;
}
return true;
}
#undef proxy_ptr

View File

@ -43,5 +43,9 @@ ladish_app_supervisor_proxy_create(
void ladish_app_supervisor_proxy_destroy(ladish_app_supervisor_proxy_handle proxy);
bool ladish_app_supervisor_proxy_run_custom(ladish_app_supervisor_proxy_handle proxy, const char * command, const char * name, bool run_in_terminal);
bool ladish_app_supervisor_proxy_start_app(ladish_app_supervisor_proxy_handle proxy, uint64_t id);
bool ladish_app_supervisor_proxy_stop_app(ladish_app_supervisor_proxy_handle proxy, uint64_t id);
bool ladish_app_supervisor_proxy_kill_app(ladish_app_supervisor_proxy_handle proxy, uint64_t id);
bool ladish_app_supervisor_proxy_remove_app(ladish_app_supervisor_proxy_handle proxy, uint64_t id);
#endif /* #ifndef APP_SUPERVISOR_PROXY_H__A48C609D_0AB6_4C91_A9B0_BC7F1B7E4CB4__INCLUDED */

View File

@ -272,3 +272,8 @@ bool app_run_custom(graph_view_handle view, const char * command, const char * n
{
return ladish_app_supervisor_proxy_run_custom(view_ptr->app_supervisor, command, name, run_in_terminal);
}
ladish_app_supervisor_proxy_handle graph_view_get_app_supervisor(graph_view_handle view)
{
return view_ptr->app_supervisor;
}

View File

@ -28,6 +28,7 @@
#define GRAPH_VIEW_H__05B5CE46_5239_43F1_9F31_79F13EBF0DFA__INCLUDED
#include "graph_canvas.h"
#include "app_supervisor_proxy.h"
typedef struct graph_view_tag { int unused; } * graph_view_handle;
@ -49,6 +50,7 @@ const char * get_view_name(graph_view_handle view);
bool set_view_name(graph_view_handle view, const char * name);
canvas_handle get_current_canvas();
ladish_app_supervisor_proxy_handle graph_view_get_app_supervisor(graph_view_handle view);
bool app_run_custom(graph_view_handle view, const char * command, const char * name, bool run_in_terminal);
/* not very good place for this prototype, because it is not implemented in graph_view.c */

View File

@ -79,22 +79,24 @@ on_select(
return TRUE;
}
bool get_selected_app_id(uint64_t * id_ptr)
bool get_selected_app_id(graph_view_handle * view_ptr, uint64_t * id_ptr)
{
GtkTreeSelection * selection;
GtkTreeIter iter;
GtkTreeIter app_iter;
GtkTreeIter view_iter;
gint type;
uint64_t id;
graph_view_handle view;
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(g_world_tree_widget));
if (!gtk_tree_selection_get_selected(selection, NULL, &iter))
if (!gtk_tree_selection_get_selected(selection, NULL, &app_iter))
{
return false;
}
gtk_tree_model_get(
GTK_TREE_MODEL(g_treestore),
&iter,
&app_iter,
COL_TYPE, &type,
COL_ID, &id,
-1);
@ -103,6 +105,25 @@ bool get_selected_app_id(uint64_t * id_ptr)
return false;
}
if (!gtk_tree_model_iter_parent(GTK_TREE_MODEL(g_treestore), &view_iter, &app_iter))
{
ASSERT_NO_PASS;
return false;
}
gtk_tree_model_get(
GTK_TREE_MODEL(g_treestore),
&view_iter,
COL_TYPE, &type,
COL_VIEW, &view,
-1);
if (type != entry_type_view)
{
ASSERT_NO_PASS;
return false;
}
*view_ptr = view;
*id_ptr = id;
return true;
@ -111,37 +132,69 @@ bool get_selected_app_id(uint64_t * id_ptr)
void on_popup_menu_action_app_start(GtkWidget * menuitem, gpointer userdata)
{
uint64_t id;
ladish_app_supervisor_proxy_handle proxy;
graph_view_handle view;
if (!get_selected_app_id(&id))
if (!get_selected_app_id(&view, &id))
{
return;
}
log_info("start app %"PRIu64, id);
proxy = graph_view_get_app_supervisor(view);
ladish_app_supervisor_proxy_start_app(proxy, id);
}
void on_popup_menu_action_app_stop(GtkWidget * menuitem, gpointer userdata)
{
uint64_t id;
ladish_app_supervisor_proxy_handle proxy;
graph_view_handle view;
if (!get_selected_app_id(&id))
if (!get_selected_app_id(&view, &id))
{
return;
}
log_info("stop app %"PRIu64, id);
proxy = graph_view_get_app_supervisor(view);
ladish_app_supervisor_proxy_stop_app(proxy, id);
}
void on_popup_menu_action_app_kill(GtkWidget * menuitem, gpointer userdata)
{
uint64_t id;
ladish_app_supervisor_proxy_handle proxy;
graph_view_handle view;
if (!get_selected_app_id(&view, &id))
{
return;
}
log_info("kill app %"PRIu64, id);
proxy = graph_view_get_app_supervisor(view);
ladish_app_supervisor_proxy_kill_app(proxy, id);
}
void on_popup_menu_action_app_remove(GtkWidget * menuitem, gpointer userdata)
{
uint64_t id;
ladish_app_supervisor_proxy_handle proxy;
graph_view_handle view;
if (!get_selected_app_id(&id))
if (!get_selected_app_id(&view, &id))
{
return;
}
log_info("remove app %"PRIu64, id);
proxy = graph_view_get_app_supervisor(view);
ladish_app_supervisor_proxy_remove_app(proxy, id);
}
void popup_menu(GtkWidget * treeview, GdkEventButton * event)
@ -197,6 +250,13 @@ void popup_menu(GtkWidget * treeview, GdkEventButton * event)
g_signal_connect(menuitem, "activate", (GCallback)on_popup_menu_action_app_remove, NULL);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
if (running)
{
menuitem = gtk_menu_item_new_with_label("Kill");
g_signal_connect(menuitem, "activate", (GCallback)on_popup_menu_action_app_kill, NULL);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
}
gtk_widget_show_all(menu);
/* Note: event can be NULL here when called from view_onPopupMenu;
@ -429,12 +489,11 @@ free_path:
gtk_tree_path_free(path);
}
void world_tree_app_state_changed(graph_view_handle view, uint64_t id, const char * name, bool running, bool terminal, uint8_t level)
void world_tree_app_state_changed(graph_view_handle view, uint64_t id, const char * app_name, bool running, bool terminal, uint8_t level)
{
GtkTreeIter view_iter;
GtkTreeIter app_iter;
const char * view_name;
const char * app_name;
GtkTreePath * path;
char * app_name_with_status;
@ -447,7 +506,6 @@ void world_tree_app_state_changed(graph_view_handle view, uint64_t id, const cha
path = gtk_tree_model_get_path(GTK_TREE_MODEL(g_treestore), &view_iter);
gtk_tree_model_get(GTK_TREE_MODEL(g_treestore), &view_iter, COL_NAME, &view_name, -1);
gtk_tree_model_get(GTK_TREE_MODEL(g_treestore), &app_iter, COL_NAME, &app_name, -1);
log_info("changing app state '%s':'%s'", view_name, app_name);