daemon: better implementation of server stop timeout workaround
* current time check is more precise * waits during command executions are suboptimal because they block the main loop
This commit is contained in:
parent
09ef9023bc
commit
fc21df8068
|
@ -0,0 +1,42 @@
|
||||||
|
/* -*- Mode: C ; c-basic-offset: 2 -*- */
|
||||||
|
/*
|
||||||
|
* LADI Session Handler (ladish)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Nedko Arnaudov <nedko@arnaudov.name>
|
||||||
|
*
|
||||||
|
**************************************************************************
|
||||||
|
* This file contains implementations of functions related to time
|
||||||
|
**************************************************************************
|
||||||
|
*
|
||||||
|
* 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 <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include "time.h"
|
||||||
|
|
||||||
|
/* TODO: implement this with uptime or find some other way to handle time shifts */
|
||||||
|
uint64_t ladish_get_current_microseconds(void)
|
||||||
|
{
|
||||||
|
struct timeval time;
|
||||||
|
|
||||||
|
if (gettimeofday(&time, NULL) != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (uint64_t)time.tv_sec * 1000000 + (uint64_t)time.tv_usec;
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/* -*- Mode: C ; c-basic-offset: 2 -*- */
|
||||||
|
/*
|
||||||
|
* LADI Session Handler (ladish)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Nedko Arnaudov <nedko@arnaudov.name>
|
||||||
|
*
|
||||||
|
**************************************************************************
|
||||||
|
* This file contains prototypes of functions related to time
|
||||||
|
**************************************************************************
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TIME_H__2E078D92_D0D7_4287_B27E_3B0F732F5989__INCLUDED
|
||||||
|
#define TIME_H__2E078D92_D0D7_4287_B27E_3B0F732F5989__INCLUDED
|
||||||
|
|
||||||
|
uint64_t ladish_get_current_microseconds(void);
|
||||||
|
|
||||||
|
#endif /* #ifndef TIME_H__2E078D92_D0D7_4287_B27E_3B0F732F5989__INCLUDED */
|
|
@ -29,6 +29,7 @@
|
||||||
#include "cmd.h"
|
#include "cmd.h"
|
||||||
#include "studio_internal.h"
|
#include "studio_internal.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
|
#include "../common/time.h"
|
||||||
|
|
||||||
struct ladish_command_start_studio
|
struct ladish_command_start_studio
|
||||||
{
|
{
|
||||||
|
@ -36,16 +37,6 @@ struct ladish_command_start_studio
|
||||||
uint64_t deadline;
|
uint64_t deadline;
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint64_t get_current_microseconds(void)
|
|
||||||
{
|
|
||||||
struct timeval time;
|
|
||||||
|
|
||||||
if (gettimeofday(&time, NULL) != 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return (uint64_t)time.tv_sec * 1000000 + (uint64_t)time.tv_usec;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define cmd_ptr ((struct ladish_command_start_studio *)context)
|
#define cmd_ptr ((struct ladish_command_start_studio *)context)
|
||||||
|
|
||||||
static bool run(void * context)
|
static bool run(void * context)
|
||||||
|
@ -83,7 +74,7 @@ static bool run(void * context)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_ptr->deadline = get_current_microseconds();
|
cmd_ptr->deadline = ladish_get_current_microseconds();
|
||||||
if (cmd_ptr->deadline != 0)
|
if (cmd_ptr->deadline != 0)
|
||||||
{
|
{
|
||||||
cmd_ptr->deadline += 5000000;
|
cmd_ptr->deadline += 5000000;
|
||||||
|
@ -97,7 +88,7 @@ static bool run(void * context)
|
||||||
/* we are still waiting for the JACK server start */
|
/* we are still waiting for the JACK server start */
|
||||||
ASSERT(!ladish_environment_get(&g_studio.env_store, ladish_environment_jack_server_started)); /* someone else consumed the state change? */
|
ASSERT(!ladish_environment_get(&g_studio.env_store, ladish_environment_jack_server_started)); /* someone else consumed the state change? */
|
||||||
|
|
||||||
if (cmd_ptr->deadline != 0 && get_current_microseconds() >= cmd_ptr->deadline)
|
if (cmd_ptr->deadline != 0 && ladish_get_current_microseconds() >= cmd_ptr->deadline)
|
||||||
{
|
{
|
||||||
log_error("Starting JACK server succeded, but 'started' signal was not received within 5 seconds.");
|
log_error("Starting JACK server succeded, but 'started' signal was not received within 5 seconds.");
|
||||||
cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE;
|
cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/*
|
/*
|
||||||
* LADI Session Handler (ladish)
|
* LADI Session Handler (ladish)
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 Nedko Arnaudov <nedko@arnaudov.name>
|
* Copyright (C) 2009, 2010 Nedko Arnaudov <nedko@arnaudov.name>
|
||||||
*
|
*
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
* This file contains implementation of the "stop studio" command
|
* This file contains implementation of the "stop studio" command
|
||||||
|
@ -29,6 +29,7 @@
|
||||||
#include "cmd.h"
|
#include "cmd.h"
|
||||||
#include "studio_internal.h"
|
#include "studio_internal.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
|
#include "../common/time.h"
|
||||||
|
|
||||||
#define STOP_STATE_WAITING_FOR_JACK_CLIENTS_DISAPPEAR 1
|
#define STOP_STATE_WAITING_FOR_JACK_CLIENTS_DISAPPEAR 1
|
||||||
#define STOP_STATE_WAITING_FOR_CHILDS_TERMINATION 2
|
#define STOP_STATE_WAITING_FOR_CHILDS_TERMINATION 2
|
||||||
|
@ -37,7 +38,7 @@
|
||||||
struct ladish_command_stop_studio
|
struct ladish_command_stop_studio
|
||||||
{
|
{
|
||||||
struct ladish_command command;
|
struct ladish_command command;
|
||||||
int stop_waits;
|
uint64_t deadline;
|
||||||
unsigned int stop_state;
|
unsigned int stop_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -102,35 +103,33 @@ static bool run(void * context)
|
||||||
/* JACK server stop sometimes fail, even if it actually succeeds after some time */
|
/* JACK server stop sometimes fail, even if it actually succeeds after some time */
|
||||||
/* Reproducable with yoshimi-0.0.45 */
|
/* Reproducable with yoshimi-0.0.45 */
|
||||||
|
|
||||||
cmd_ptr->stop_waits = 5000;
|
cmd_ptr->deadline = ladish_get_current_microseconds();
|
||||||
|
if (cmd_ptr->deadline != 0)
|
||||||
|
{
|
||||||
|
cmd_ptr->deadline += 5000000;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(cmd_ptr->stop_state == STOP_STATE_WAITING_FOR_JACK_SERVER_STOP);
|
ASSERT(cmd_ptr->stop_state == STOP_STATE_WAITING_FOR_JACK_SERVER_STOP);
|
||||||
|
|
||||||
if (cmd_ptr->stop_waits > 0)
|
if (cmd_ptr->deadline != 0)
|
||||||
{
|
{
|
||||||
if (!jack_proxy_is_started(&jack_server_started))
|
if (jack_proxy_is_started(&jack_server_started) && !jack_server_started)
|
||||||
{
|
|
||||||
log_error("jack_proxy_is_started() failed.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!jack_server_started)
|
|
||||||
{
|
{
|
||||||
ladish_environment_reset_stealth(&g_studio.env_store, ladish_environment_jack_server_started);
|
ladish_environment_reset_stealth(&g_studio.env_store, ladish_environment_jack_server_started);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd_ptr->stop_waits == 1)
|
if (ladish_get_current_microseconds() >= cmd_ptr->deadline)
|
||||||
{
|
{
|
||||||
log_error("JACK server stop wait after stop request expired.");
|
log_error("JACK server stop wait after stop request expired (5 seconds).");
|
||||||
|
cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_ptr->stop_waits--;
|
|
||||||
usleep(1000);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +173,7 @@ bool ladish_command_stop_studio(void * call_ptr, struct ladish_cqueue * queue_pt
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_ptr->command.run = run;
|
cmd_ptr->command.run = run;
|
||||||
cmd_ptr->stop_waits = -1;
|
cmd_ptr->deadline = 0;
|
||||||
|
|
||||||
if (!ladish_cqueue_add_command(queue_ptr, &cmd_ptr->command))
|
if (!ladish_cqueue_add_command(queue_ptr, &cmd_ptr->command))
|
||||||
{
|
{
|
||||||
|
|
6
wscript
6
wscript
|
@ -246,7 +246,11 @@ def build(bld):
|
||||||
]:
|
]:
|
||||||
daemon.source.append(os.path.join("dbus", source))
|
daemon.source.append(os.path.join("dbus", source))
|
||||||
|
|
||||||
daemon.source.append(os.path.join("common", "safety.c"))
|
for source in [
|
||||||
|
'safety.c',
|
||||||
|
'time.c',
|
||||||
|
]:
|
||||||
|
daemon.source.append(os.path.join("common", source))
|
||||||
|
|
||||||
# process name.arnaudov.nedko.ladish.service.in -> name.arnaudov.nedko.ladish.service
|
# process name.arnaudov.nedko.ladish.service.in -> name.arnaudov.nedko.ladish.service
|
||||||
import misc
|
import misc
|
||||||
|
|
Loading…
Reference in New Issue