daemon: set proper state after JACK server stop is detected in the hard way
[ladish.git] / daemon / cmd_stop_studio.c
blobc6994134d94a53b2525268327a4e214a3dc5907d
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2009 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"
32 struct ladish_command_stop_studio
34 struct ladish_command command;
35 int stop_waits;
38 #define cmd_ptr ((struct ladish_command_stop_studio *)context)
40 static bool run(void * context)
42 bool jack_server_started;
44 switch (cmd_ptr->command.state)
46 case LADISH_COMMAND_STATE_PENDING:
47 if (!studio_is_started())
49 log_info("Ignoring stop request because studio is already stopped.");
50 /* nothing to do, studio is not running */
51 cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE;
52 return true;
55 ladish_app_supervisor_stop(g_studio.app_supervisor);
57 log_info("Stopping JACK server...");
59 ladish_graph_dump(g_studio.studio_graph);
61 if (!jack_proxy_stop_server())
63 log_error("Stopping JACK server failed. Waiting stop for 5 seconds anyway...");
65 /* JACK server stop sometimes fail, even if it actually succeeds after some time */
66 /* Reproducable with yoshimi-0.0.45 */
68 cmd_ptr->stop_waits = 5000;
69 cmd_ptr->command.state = LADISH_COMMAND_STATE_WAITING;
70 return true;
73 cmd_ptr->command.state = LADISH_COMMAND_STATE_WAITING;
74 /* fall through */
75 case LADISH_COMMAND_STATE_WAITING:
76 if (cmd_ptr->stop_waits > 0)
78 if (!jack_proxy_is_started(&jack_server_started))
80 log_error("jack_proxy_is_started() failed.");
81 return false;
84 if (!jack_server_started)
86 ladish_environment_reset_stealth(&g_studio.env_store, ladish_environment_jack_server_started);
87 goto done;
90 if (cmd_ptr->stop_waits == 1)
92 log_error("JACK server stop wait after stop request expired.");
93 return false;
96 cmd_ptr->stop_waits--;
97 usleep(1000);
98 return true;
101 if (!ladish_environment_consume_change(&g_studio.env_store, ladish_environment_jack_server_started, &jack_server_started))
103 /* we are still waiting for the JACK server stop */
104 ASSERT(ladish_environment_get(&g_studio.env_store, ladish_environment_jack_server_started)); /* someone else consumed the state change? */
105 return true;
108 done:
109 log_info("Wait for JACK server stop complete.");
111 ladish_graph_hide_all(g_studio.jack_graph);
112 ladish_graph_hide_all(g_studio.studio_graph);
113 ASSERT(!jack_server_started);
115 ladish_graph_dump(g_studio.studio_graph);
117 on_event_jack_stopped();
119 cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE;
120 return true;
123 ASSERT_NO_PASS;
124 return false;
127 #undef cmd_ptr
129 bool ladish_command_stop_studio(void * call_ptr, struct ladish_cqueue * queue_ptr)
131 struct ladish_command_stop_studio * cmd_ptr;
133 cmd_ptr = ladish_command_new(sizeof(struct ladish_command_stop_studio));
134 if (cmd_ptr == NULL)
136 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "ladish_command_new() failed.");
137 goto fail;
140 cmd_ptr->command.run = run;
141 cmd_ptr->stop_waits = -1;
143 if (!ladish_cqueue_add_command(queue_ptr, &cmd_ptr->command))
145 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "ladish_cqueue_add_command() failed.");
146 goto fail_destroy_command;
149 return true;
151 fail_destroy_command:
152 free(cmd_ptr);
154 fail:
155 return false;