daemon: handle start_app requests asynchronously

This commit is contained in:
Nedko Arnaudov 2010-05-05 01:09:42 +03:00
parent 7c10be38cf
commit bb7a63e216
5 changed files with 170 additions and 32 deletions

View File

@ -105,7 +105,7 @@ ladish_app_supervisor_create(
return true;
}
struct ladish_app * ladish_app_supervisor_find_app_by_id(struct ladish_app_supervisor * supervisor_ptr, uint64_t id)
struct ladish_app * ladish_app_supervisor_find_app_by_id_internal(struct ladish_app_supervisor * supervisor_ptr, uint64_t id)
{
struct list_head * node_ptr;
struct ladish_app * app_ptr;
@ -193,6 +193,11 @@ ladish_app_handle ladish_app_supervisor_find_app_by_name(ladish_app_supervisor_h
return NULL;
}
ladish_app_handle ladish_app_supervisor_find_app_by_id(ladish_app_supervisor_handle supervisor_handle, uint64_t id)
{
return (ladish_app_handle)ladish_app_supervisor_find_app_by_id_internal(supervisor_ptr, id);
}
ladish_app_handle
ladish_app_supervisor_add(
ladish_app_supervisor_handle supervisor_handle,
@ -347,6 +352,8 @@ ladish_app_supervisor_enum(
bool ladish_app_supervisor_run(ladish_app_supervisor_handle supervisor_handle, ladish_app_handle app_handle)
{
app_ptr->zombie = false;
if (!loader_execute(supervisor_ptr->name, app_ptr->name, "/", app_ptr->terminal, app_ptr->commandline, &app_ptr->pid))
{
return false;
@ -361,6 +368,16 @@ void ladish_app_supervisor_remove(ladish_app_supervisor_handle supervisor_handle
remove_app_internal(supervisor_ptr, app_ptr);
}
bool ladish_app_is_running(ladish_app_handle app_handle)
{
return app_ptr->pid != 0;
}
const char * ladish_app_get_name(ladish_app_handle app_handle)
{
return app_ptr->name;
}
#undef app_ptr
void ladish_app_supervisor_autorun(ladish_app_supervisor_handle supervisor_handle)
@ -386,8 +403,6 @@ void ladish_app_supervisor_autorun(ladish_app_supervisor_handle supervisor_handl
log_error("Execution of '%s' failed", app_ptr->commandline);
return;
}
emit_app_state_changed(supervisor_ptr, app_ptr);
}
}
@ -591,7 +606,6 @@ static void run_custom(struct dbus_method_call * call_ptr)
static void start_app(struct dbus_method_call * call_ptr)
{
uint64_t id;
struct ladish_app * app_ptr;
if (!dbus_message_get_args(
call_ptr->message,
@ -604,30 +618,10 @@ static void start_app(struct dbus_method_call * call_ptr)
return;
}
app_ptr = ladish_app_supervisor_find_app_by_id(supervisor_ptr, id);
if (app_ptr == NULL)
if (ladish_command_start_app(call_ptr, ladish_studio_get_cmd_queue(), supervisor_ptr->opath, id))
{
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "App with ID %"PRIu64" not found", id);
return;
method_return_new_void(call_ptr);
}
if (app_ptr->pid != 0)
{
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "App %s is already running", app_ptr->name);
return;
}
app_ptr->zombie = false;
if (!ladish_app_supervisor_run((ladish_app_supervisor_handle)supervisor_ptr, (ladish_app_handle)app_ptr))
{
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);
}
static void stop_app(struct dbus_method_call * call_ptr)
@ -646,7 +640,7 @@ static void stop_app(struct dbus_method_call * call_ptr)
return;
}
app_ptr = ladish_app_supervisor_find_app_by_id(supervisor_ptr, id);
app_ptr = ladish_app_supervisor_find_app_by_id_internal(supervisor_ptr, id);
if (app_ptr == NULL)
{
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "App with ID %"PRIu64" not found", id);
@ -680,7 +674,7 @@ static void kill_app(struct dbus_method_call * call_ptr)
return;
}
app_ptr = ladish_app_supervisor_find_app_by_id(supervisor_ptr, id);
app_ptr = ladish_app_supervisor_find_app_by_id_internal(supervisor_ptr, id);
if (app_ptr == NULL)
{
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "App with ID %"PRIu64" not found", id);
@ -716,7 +710,7 @@ static void get_app_properties(struct dbus_method_call * call_ptr)
return;
}
app_ptr = ladish_app_supervisor_find_app_by_id(supervisor_ptr, id);
app_ptr = ladish_app_supervisor_find_app_by_id_internal(supervisor_ptr, id);
if (app_ptr == NULL)
{
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "App with ID %"PRIu64" not found", id);
@ -780,7 +774,7 @@ static void set_app_properties(struct dbus_method_call * call_ptr)
return;
}
app_ptr = ladish_app_supervisor_find_app_by_id(supervisor_ptr, id);
app_ptr = ladish_app_supervisor_find_app_by_id_internal(supervisor_ptr, id);
if (app_ptr == NULL)
{
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "App with ID %"PRIu64" not found", id);
@ -874,7 +868,7 @@ static void remove_app(struct dbus_method_call * call_ptr)
return;
}
app_ptr = ladish_app_supervisor_find_app_by_id(supervisor_ptr, id);
app_ptr = ladish_app_supervisor_find_app_by_id_internal(supervisor_ptr, id);
if (app_ptr == NULL)
{
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "App with ID %"PRIu64" not found", id);
@ -911,7 +905,7 @@ static void is_app_running(struct dbus_method_call * call_ptr)
return;
}
app_ptr = ladish_app_supervisor_find_app_by_id(supervisor_ptr, id);
app_ptr = ladish_app_supervisor_find_app_by_id_internal(supervisor_ptr, id);
if (app_ptr == NULL)
{
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "App with ID %"PRIu64" not found", id);

View File

@ -84,9 +84,13 @@ ladish_app_supervisor_search_app(
const char * ladish_app_supervisor_get_name(ladish_app_supervisor_handle supervisor_handle);
unsigned int ladish_app_supervisor_get_running_app_count(ladish_app_supervisor_handle supervisor_handle);
ladish_app_handle ladish_app_supervisor_find_app_by_name(ladish_app_supervisor_handle supervisor_handle, const char * name);
ladish_app_handle ladish_app_supervisor_find_app_by_id(ladish_app_supervisor_handle supervisor_handle, uint64_t id);
const char * ladish_app_supervisor_get_opath(ladish_app_supervisor_handle supervisor_handle);
bool ladish_app_supervisor_run(ladish_app_supervisor_handle supervisor_handle, ladish_app_handle app_handle);
void ladish_app_supervisor_remove(ladish_app_supervisor_handle supervisor_handle, ladish_app_handle app_handle);
const char * ladish_app_get_commandline(ladish_app_handle app_handle);
bool ladish_app_is_running(ladish_app_handle app_handle);
const char * ladish_app_get_name(ladish_app_handle app_handle);
extern const struct dbus_interface_descriptor g_iface_app_supervisor;

View File

@ -80,4 +80,6 @@ ladish_command_new_app(
const char * name,
uint8_t level);
bool ladish_command_start_app(void * call_ptr, struct ladish_cqueue * queue_ptr, const char * opath, uint64_t id);
#endif /* #ifndef CMD_H__28542C9B_7CB8_40F8_BBB6_DCE13CBB1E7F__INCLUDED */

137
daemon/cmd_start_app.c Normal file
View File

@ -0,0 +1,137 @@
/* -*- Mode: C ; c-basic-offset: 2 -*- */
/*
* LADI Session Handler (ladish)
*
* Copyright (C) 2010 Nedko Arnaudov <nedko@arnaudov.name>
*
**************************************************************************
* This file contains implementation of the "start app" command
**************************************************************************
*
* LADI Session Handler is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* LADI Session Handler is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
* or write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <ctype.h>
#include "cmd.h"
#include "studio.h"
#include "../dbus/error.h"
#include "../proxies/notify_proxy.h"
struct ladish_command_start_app
{
struct ladish_command command; /* must be the first member */
char * opath;
uint64_t id;
};
#define cmd_ptr ((struct ladish_command_start_app *)context)
static bool run(void * context)
{
ladish_app_supervisor_handle supervisor;
ladish_app_handle app;
ASSERT(cmd_ptr->command.state == LADISH_COMMAND_STATE_PENDING);
log_info("start_app command. opath='%s'", cmd_ptr->opath);
if (!ladish_studio_is_started())
{
log_error("cannot start app because studio is not started", cmd_ptr->opath);
ladish_notify_simple(LADISH_NOTIFY_URGENCY_HIGH, "Cannot start app because studio is not started", NULL);
return false;
}
supervisor = ladish_studio_find_app_supervisor(cmd_ptr->opath);
if (supervisor == NULL)
{
log_error("cannot find supervisor '%s' to start app", cmd_ptr->opath);
ladish_notify_simple(LADISH_NOTIFY_URGENCY_HIGH, "Cannot start app because of internal error (unknown supervisor)", NULL);
return false;
}
app = ladish_app_supervisor_find_app_by_id(supervisor, cmd_ptr->id);
if (app == NULL)
{
log_error("App with ID %"PRIu64" not found", cmd_ptr->id);
ladish_notify_simple(LADISH_NOTIFY_URGENCY_HIGH, "Cannot start app because it is not found", NULL);
return false;
}
if (ladish_app_is_running(app))
{
log_error("App %s is already running", ladish_app_get_name(app));
ladish_notify_simple(LADISH_NOTIFY_URGENCY_HIGH, "Cannot start app because it is already running", NULL);
return false;
}
if (!ladish_app_supervisor_run(supervisor, app))
{
ladish_notify_simple(LADISH_NOTIFY_URGENCY_HIGH, "Cannot start app (execution failed)", NULL);
return false;
}
cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE;
return true;
}
static void destructor(void * context)
{
log_info("start_app command destructor");
free(cmd_ptr->opath);
}
#undef cmd_ptr
bool ladish_command_start_app(void * call_ptr, struct ladish_cqueue * queue_ptr, const char * opath, uint64_t id)
{
struct ladish_command_start_app * cmd_ptr;
char * opath_dup;
opath_dup = strdup(opath);
if (opath_dup == NULL)
{
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "strdup('%s') failed.", opath_dup);
goto fail;
}
cmd_ptr = ladish_command_new(sizeof(struct ladish_command_start_app));
if (cmd_ptr == NULL)
{
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "ladish_command_new() failed.");
goto fail_free_opath;
}
cmd_ptr->command.run = run;
cmd_ptr->command.destructor = destructor;
cmd_ptr->opath = opath_dup;
cmd_ptr->id = id;
if (!ladish_cqueue_add_command(queue_ptr, &cmd_ptr->command))
{
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "ladish_cqueue_add_command() failed.");
goto fail_destroy_command;
}
return true;
fail_destroy_command:
free(cmd_ptr);
fail_free_opath:
free(opath_dup);
fail:
return false;
}

View File

@ -229,6 +229,7 @@ def build(bld):
'cmd_stop_studio.c',
'cmd_unload_studio.c',
'cmd_new_app.c',
'cmd_start_app.c',
'cmd_exit.c',
'cqueue.c',
'app_supervisor.c',