daemon: fix incorrect identifiers
[ladish.git] / daemon / cmd_stop_studio.c
bloba5cbc79ca29d03a471b24e5941a108dbf534fb9e
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2009, 2010 Nedko Arnaudov <nedko@arnaudov.name>
7 **************************************************************************
8 * This file contains implementation of the "stop studio" command
9 **************************************************************************
11 * LADI Session Handler is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * LADI Session Handler is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
23 * or write to the Free Software Foundation, Inc.,
24 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include <unistd.h>
29 #include "cmd.h"
30 #include "studio_internal.h"
31 #include "loader.h"
32 #include "../common/time.h"
33 #include "studio.h"
35 #define STOP_STATE_WAITING_FOR_JACK_CLIENTS_DISAPPEAR 1
36 #define STOP_STATE_WAITING_FOR_CHILDS_TERMINATION 2
37 #define STOP_STATE_WAITING_FOR_JACK_SERVER_STOP 3
39 struct ladish_command_stop_studio
41 struct ladish_command command;
42 uint64_t deadline;
43 unsigned int stop_state;
46 #define cmd_ptr ((struct ladish_command_stop_studio *)context)
48 static bool run(void * context)
50 bool jack_server_started;
51 unsigned int clients_count;
53 switch (cmd_ptr->command.state)
55 case LADISH_COMMAND_STATE_PENDING:
56 if (!ladish_studio_is_started())
58 log_info("Ignoring stop request because studio is already stopped.");
59 /* nothing to do, studio is not running */
60 cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE;
61 return true;
64 ladish_graph_dump(g_studio.jack_graph);
65 ladish_graph_dump(g_studio.studio_graph);
67 ladish_studio_stop_app_supervisors();
69 cmd_ptr->command.state = LADISH_COMMAND_STATE_WAITING;
70 cmd_ptr->stop_state = STOP_STATE_WAITING_FOR_JACK_CLIENTS_DISAPPEAR;
71 /* fall through */
72 case LADISH_COMMAND_STATE_WAITING:
73 if (cmd_ptr->stop_state == STOP_STATE_WAITING_FOR_JACK_CLIENTS_DISAPPEAR)
75 clients_count = ladish_virtualizer_get_our_clients_count(g_studio.virtualizer);
76 log_info("%u JACK clients started by ladish are visible", clients_count);
77 if (clients_count != 0)
79 return true;
82 cmd_ptr->stop_state = STOP_STATE_WAITING_FOR_CHILDS_TERMINATION;
85 if (cmd_ptr->stop_state == STOP_STATE_WAITING_FOR_CHILDS_TERMINATION)
87 clients_count = loader_get_app_count();
88 log_info("%u child processes are running", clients_count);
89 if (clients_count != 0)
91 return true;
94 log_info("Stopping JACK server...");
96 ladish_graph_dump(g_studio.studio_graph);
98 cmd_ptr->stop_state = STOP_STATE_WAITING_FOR_JACK_SERVER_STOP;
100 if (!jack_proxy_stop_server())
102 log_error("Stopping JACK server failed. Waiting stop for 5 seconds anyway...");
104 /* JACK server stop sometimes fail, even if it actually succeeds after some time */
105 /* Reproducable with yoshimi-0.0.45 */
107 cmd_ptr->deadline = ladish_get_current_microseconds();
108 if (cmd_ptr->deadline != 0)
110 cmd_ptr->deadline += 5000000;
113 return true;
117 ASSERT(cmd_ptr->stop_state == STOP_STATE_WAITING_FOR_JACK_SERVER_STOP);
119 if (cmd_ptr->deadline != 0)
121 if (jack_proxy_is_started(&jack_server_started) && !jack_server_started)
123 ladish_environment_reset_stealth(&g_studio.env_store, ladish_environment_jack_server_started);
124 goto done;
127 if (ladish_get_current_microseconds() >= cmd_ptr->deadline)
129 log_error("JACK server stop wait after stop request expired (5 seconds).");
130 cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE;
131 return false;
134 return true;
137 if (!ladish_environment_consume_change(&g_studio.env_store, ladish_environment_jack_server_started, &jack_server_started))
139 /* we are still waiting for the JACK server stop */
140 ASSERT(ladish_environment_get(&g_studio.env_store, ladish_environment_jack_server_started)); /* someone else consumed the state change? */
141 return true;
144 done:
145 log_info("Wait for JACK server stop complete.");
147 ladish_graph_hide_non_virtual(g_studio.jack_graph);
148 ladish_graph_hide_non_virtual(g_studio.studio_graph);
149 ASSERT(!jack_server_started);
151 ladish_graph_dump(g_studio.studio_graph);
153 ladish_studio_on_event_jack_stopped();
155 cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE;
156 return true;
159 ASSERT_NO_PASS;
160 return false;
163 #undef cmd_ptr
165 bool ladish_command_stop_studio(void * call_ptr, struct ladish_cqueue * queue_ptr)
167 struct ladish_command_stop_studio * cmd_ptr;
169 cmd_ptr = ladish_command_new(sizeof(struct ladish_command_stop_studio));
170 if (cmd_ptr == NULL)
172 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "ladish_command_new() failed.");
173 goto fail;
176 cmd_ptr->command.run = run;
177 cmd_ptr->deadline = 0;
179 if (!ladish_cqueue_add_command(queue_ptr, &cmd_ptr->command))
181 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "ladish_cqueue_add_command() failed.");
182 goto fail_destroy_command;
185 return true;
187 fail_destroy_command:
188 free(cmd_ptr);
190 fail:
191 return false;