speechd: Use alternative `pthread_cancel` workaround

This commit is contained in:
Tee KOBAYASHI 2022-12-13 10:14:44 +09:00 committed by xtkoba
parent 265b425b29
commit 729d04f152
4 changed files with 192 additions and 90 deletions

View File

@ -3,19 +3,13 @@ TERMUX_PKG_DESCRIPTION="Common interface to speech synthesis"
TERMUX_PKG_LICENSE="LGPL-2.1, GPL-2.0"
TERMUX_PKG_MAINTAINER="@termux"
TERMUX_PKG_VERSION="0.11.4"
TERMUX_PKG_REVISION=1
TERMUX_PKG_SHA256=628d4446894b47f0df099123924c1070180b5b5b09c5b637ebe80d8578fba92f
TERMUX_PKG_SRCURL=https://github.com/brailcom/speechd/archive/${TERMUX_PKG_VERSION}.tar.gz
TERMUX_PKG_DEPENDS="dotconf, espeak, glib, libiconv, pulseaudio, python"
TERMUX_PKG_DEPENDS="dotconf, espeak, glib, libiconv, libltdl, libsndfile, pulseaudio, python, speechd-data"
TERMUX_PKG_BUILD_DEPENDS="libiconv-static, libsndfile-static"
TERMUX_PKG_AUTO_UPDATE=true
##
## Note: package needs patching for proper fix of pthread_cancel usage.
## Right now it uses pthread_kill(t, 0) which does nothing and is not
## correct solution to the missing pthread_cancel on Android OS.
## See package "calcurse" for example of proper pthread_cancel replacement.
##
# Fails to find generated headers
TERMUX_PKG_BUILD_IN_SRC=true
TERMUX_PKG_EXTRA_CONFIGURE_ARGS="
@ -36,6 +30,15 @@ termux_step_pre_configure() {
source $TERMUX_SCRIPTDIR/packages/python/build.sh
echo $_MAJOR_VERSION
)
termux_setup_python_crossenv
pushd $TERMUX_PYTHON_CROSSENV_SRCDIR
_CROSSENV_PREFIX=$TERMUX_PKG_BUILDDIR/python-crossenv-prefix
python${_PYTHON_VERSION} -m crossenv \
$TERMUX_PREFIX/bin/python${_PYTHON_VERSION} \
${_CROSSENV_PREFIX}
popd
. ${_CROSSENV_PREFIX}/bin/activate
export am_cv_python_pythondir="${TERMUX_PREFIX}/lib/python${_PYTHON_VERSION}/site-packages"
export am_cv_python_pyexecdir="$am_cv_python_pythondir"
./build.sh

View File

@ -0,0 +1,176 @@
--- a/src/api/c/libspeechd.c
+++ b/src/api/c/libspeechd.c
@@ -610,7 +610,11 @@ void spd_close(SPDConnection * connectio
pthread_mutex_lock(&connection->ssip_mutex);
if (connection->mode == SPD_MODE_THREADED) {
+#ifndef __ANDROID__
pthread_cancel(connection->td->events_thread);
+#else
+ pthread_kill(connection->td->events_thread, SIGUSR2);
+#endif
pthread_mutex_destroy(&connection->td->mutex_reply_ready);
pthread_mutex_destroy(&connection->td->mutex_reply_ack);
pthread_cond_destroy(&connection->td->cond_reply_ready);
@@ -1842,12 +1846,28 @@ static char *get_reply(SPDConnection * c
return reply;
}
+#ifdef __ANDROID__
+static void thread_signal_handler(int signum)
+{
+ pthread_exit(0);
+}
+#endif
+
static void *spd_events_handler(void *conn)
{
char *reply;
int reply_code;
SPDConnection *connection = conn;
+#ifdef __ANDROID__
+ struct sigaction actions;
+ memset(&actions, 0, sizeof(actions));
+ sigemptyset(&actions.sa_mask);
+ actions.sa_flags = 0;
+ actions.sa_handler = thread_signal_handler;
+ sigaction(SIGUSR2, &actions, NULL);
+#endif
+
while (1) {
/* Read the reply/event (block if none is available) */
--- a/src/audio/nas.c
+++ b/src/audio/nas.c
@@ -51,11 +51,27 @@ typedef struct {
static int nas_log_level;
+#ifdef __ANDROID__
+static void thread_signal_handler(int signum)
+{
+ pthread_exit(0);
+}
+#endif
+
/* Internal event handler */
static void *_nas_handle_events(void *par)
{
spd_nas_id_t *nas_id = (spd_nas_id_t *) par;
+#ifndef __ANDROID__
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+#else
+ struct sigaction actions;
+ memset(&actions, 0, sizeof(actions));
+ sigemptyset(&actions.sa_mask);
+ actions.sa_flags = 0;
+ actions.sa_handler = thread_signal_handler;
+ sigaction(SIGUSR2, &actions, NULL);
+#endif
while (1)
AuHandleEvents(nas_id->aud);
@@ -214,7 +230,11 @@ static int nas_close(AudioID * id)
if (nas_id == NULL)
return -2;
+#ifndef __ANDROID__
pthread_cancel(nas_id->nas_event_handler);
+#else
+ pthread_kill(nas_id->nas_event_handler, SIGUSR2);
+#endif
pthread_join(nas_id->nas_event_handler, NULL);
pthread_mutex_destroy(&nas_id->pt_mutex);
--- a/src/common/common.c
+++ b/src/common/common.c
@@ -47,8 +47,24 @@ int spd_pthread_create(pthread_t *thread
return ret;
}
+#ifdef __ANDROID__
+static void thread_signal_handler(int signum)
+{
+ pthread_exit(0);
+}
+#endif
+
void set_speaking_thread_parameters(void)
{
+#ifndef __ANDROID__
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+#else
+ struct sigaction actions;
+ memset(&actions, 0, sizeof(actions));
+ sigemptyset(&actions.sa_mask);
+ actions.sa_flags = 0;
+ actions.sa_handler = thread_signal_handler;
+ sigaction(SIGUSR2, &actions, NULL);
+#endif
}
--- a/src/modules/module_utils.c
+++ b/src/modules/module_utils.c
@@ -586,7 +586,11 @@ int module_terminate_thread(pthread_t th
{
int ret;
+#ifndef __ANDROID__
ret = pthread_cancel(thread);
+#else
+ ret = pthread_kill(thread, SIGUSR2);
+#endif
if (ret != 0) {
DBG("Cancellation of speak thread failed");
return 1;
--- a/src/server/output.c
+++ b/src/server/output.c
@@ -225,7 +225,16 @@ void
static output_lock(void)
{
if (pthread_self() == speak_thread)
+#ifndef __ANDROID__
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
+#else
+ {
+ sigset_t pthread_cancel_block;
+ sigemptyset(&pthread_cancel_block);
+ sigaddset(&pthread_cancel_block, SIGUSR2);
+ sigprocmask(SIG_BLOCK, &pthread_cancel_block, NULL);
+ }
+#endif
pthread_mutex_lock(&output_layer_mutex);
}
@@ -234,7 +243,16 @@ static output_unlock(void)
{
pthread_mutex_unlock(&output_layer_mutex);
if (pthread_self() == speak_thread)
+#ifndef __ANDROID__
pthread_setcancelstate(oldstate, NULL);
+#else
+ {
+ sigset_t pthread_cancel_block;
+ sigemptyset(&pthread_cancel_block);
+ sigaddset(&pthread_cancel_block, SIGUSR2);
+ sigprocmask(SIG_UNBLOCK, &pthread_cancel_block, NULL);
+ }
+#endif
}
#define OL_RET(value) \
--- a/src/server/speechd.c
+++ b/src/server/speechd.c
@@ -1353,7 +1353,11 @@ int main(int argc, char *argv[])
g_hash_table_destroy(fd_settings);
MSG(4, "Closing speak() thread...");
+#ifndef __ANDROID__
ret = pthread_cancel(speak_thread);
+#else
+ ret = pthread_kill(speak_thread, SIGUSR2);
+#endif
if (ret != 0)
FATAL("Speak thread failed to cancel!\n");

View File

@ -0,0 +1,5 @@
TERMUX_SUBPKG_DESCRIPTION="Platform-independent data for speechd"
TERMUX_SUBPKG_PLATFORM_INDEPENDENT=true
TERMUX_SUBPKG_INCLUDE="share/speech-dispatcher/"
TERMUX_SUBPKG_BREAKS="speechd (<< 0.11.4-1)"
TERMUX_SUBPKG_REPLACES="speechd (<< 0.11.4-1)"

View File

@ -1,82 +0,0 @@
--- a/src/server/speechd.c 2022-04-15 04:49:54.443394249 +0000
+++ b/src/server/speechd.c 2022-04-15 06:14:44.973486291 +0000
@@ -1353,7 +1353,7 @@
g_hash_table_destroy(fd_settings);
MSG(4, "Closing speak() thread...");
- ret = pthread_cancel(speak_thread);
+ ret = pthread_kill(speak_thread, 0);
if (ret != 0)
FATAL("Speak thread failed to cancel!\n");
--- a/src/modules/module_utils.c 2022-04-15 04:49:54.468395993 +0000
+++ b/src/modules/module_utils.c 2022-04-15 06:07:29.462108958 +0000
@@ -584,7 +584,7 @@
{
int ret;
- ret = pthread_cancel(thread);
+ ret = pthread_kill(thread, 0);
if (ret != 0) {
DBG("Cancellation of speak thread failed");
return 1;
--- a/src/audio/nas.c 2022-04-15 04:49:54.442394179 +0000
+++ b/src/audio/nas.c 2022-04-15 05:57:51.188773780 +0000
@@ -51,8 +51,6 @@
static void *_nas_handle_events(void *par)
{
spd_nas_id_t *nas_id = (spd_nas_id_t *) par;
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
-
while (1)
AuHandleEvents(nas_id->aud);
@@ -208,7 +206,7 @@
if (nas_id == NULL)
return -2;
- pthread_cancel(nas_id->nas_event_handler);
+ pthread_kill(nas_id->nas_event_handler,0);
pthread_join(nas_id->nas_event_handler, NULL);
pthread_mutex_destroy(&nas_id->pt_mutex);
--- a/src/api/c/libspeechd.c 2022-04-15 04:49:54.445394389 +0000
+++ b/src/api/c/libspeechd.c 2022-04-15 05:47:47.292651531 +0000
@@ -607,7 +607,7 @@
pthread_mutex_lock(&connection->ssip_mutex);
if (connection->mode == SPD_MODE_THREADED) {
- pthread_cancel(connection->td->events_thread);
+ pthread_kill(connection->td->events_thread, 0);
pthread_mutex_destroy(&connection->td->mutex_reply_ready);
pthread_mutex_destroy(&connection->td->mutex_reply_ack);
pthread_cond_destroy(&connection->td->cond_reply_ready);
--- a/src/common/common.c 2022-04-15 04:49:54.442394179 +0000
+++ b/src/common/common.c 2022-04-15 14:25:51.987242432 +0000
@@ -49,6 +49,4 @@
void set_speaking_thread_parameters(void)
{
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
- pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
}
--- a/src/server/output.c 2022-04-15 04:49:54.443394249 +0000
+++ b/src/server/output.c 2022-04-15 14:30:36.748824687 +0000
@@ -218,8 +218,6 @@
void
static output_lock(void)
{
- if (pthread_self() == speak_thread)
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
pthread_mutex_lock(&output_layer_mutex);
}
@@ -227,8 +225,6 @@
static output_unlock(void)
{
pthread_mutex_unlock(&output_layer_mutex);
- if (pthread_self() == speak_thread)
- pthread_setcancelstate(oldstate, NULL);
}
#define OL_RET(value) \