Package: espeak-ng / 1.49.2+dfsg-8

nocancel Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
---
 src/libespeak-ng/event.c |   15 ++++++++++-----
 src/libespeak-ng/fifo.c  |   15 +++++++++------
 2 files changed, 19 insertions(+), 11 deletions(-)

--- a/src/libespeak-ng/event.c
+++ b/src/libespeak-ng/event.c
@@ -44,6 +44,7 @@ static pthread_cond_t my_cond_stop_is_re
 static int my_stop_is_required = 0;
 static pthread_cond_t my_cond_stop_is_acknowledged;
 static int my_stop_is_acknowledged = 0;
+static int my_terminate_is_required = 0;
 // my_thread: polls the audio duration and compares it to the duration of the first event.
 static pthread_t my_thread;
 static bool thread_inited;
@@ -254,13 +255,13 @@ static void *polling_thread(void *p)
 {
 	(void)p; // unused
 
-	while (1) {
+	while (my_terminate_is_required == 0) {
 		int a_stop_is_required = 0;
 
 		int a_status = pthread_mutex_lock(&my_mutex);
 		my_event_is_running = 0;
 
-		while (my_start_is_required == 0) {
+		while (my_start_is_required == 0 && my_terminate_is_required == 0) {
 			while ((pthread_cond_wait(&my_cond_start_is_required, &my_mutex) == -1) && errno == EINTR)
 				continue; // Restart when interrupted by handler
 		}
@@ -272,7 +273,7 @@ static void *polling_thread(void *p)
 		pthread_mutex_unlock(&my_mutex);
 
 		// In this loop, my_event_is_running = 1
-		while (head && (a_stop_is_required == 0)) {
+		while (head && (a_stop_is_required == 0) && (my_terminate_is_required == 0)) {
 			espeak_EVENT *event = (espeak_EVENT *)(head->data);
 			assert(event);
 
@@ -305,7 +306,7 @@ static void *polling_thread(void *p)
 
 		a_status = pthread_mutex_unlock(&my_mutex);
 
-		if (a_stop_is_required > 0) {
+		if (a_stop_is_required > 0 || my_terminate_is_required) {
 			// no mutex required since the stop command is synchronous
 			// and waiting for my_cond_stop_is_acknowledged
 			init();
@@ -385,8 +386,12 @@ static void init()
 void event_terminate()
 {
 	if (thread_inited) {
-		pthread_cancel(my_thread);
+		my_terminate_is_required = 1;
+		pthread_cond_signal(&my_cond_start_is_required);
+		pthread_cond_signal(&my_cond_stop_is_required);
 		pthread_join(my_thread, NULL);
+		my_terminate_is_required = 0;
+
 		pthread_mutex_destroy(&my_mutex);
 		pthread_cond_destroy(&my_cond_start_is_required);
 		pthread_cond_destroy(&my_cond_stop_is_required);
--- a/src/libespeak-ng/fifo.c
+++ b/src/libespeak-ng/fifo.c
@@ -45,6 +45,7 @@ static pthread_mutex_t my_mutex;
 static int my_command_is_running = 0;
 static pthread_cond_t my_cond_command_is_running;
 static int my_stop_is_required = 0;
+static int my_terminate_is_required = 0;
 
 // my_thread: reads commands from the fifo, and runs them.
 static pthread_t my_thread;
@@ -289,7 +290,7 @@ static void *say_thread(void *p)
 
 	int look_for_inactivity = 0;
 
-	while (1) {
+	while (my_terminate_is_required == 0) {
 		int a_start_is_required = 0;
 		if (look_for_inactivity) {
 			a_start_is_required = sleep_until_start_request_or_inactivity();
@@ -302,19 +303,18 @@ static void *say_thread(void *p)
 		assert(!a_status);
 
 		if (!a_start_is_required) {
-			while (my_start_is_required == 0) {
+			while (my_start_is_required == 0 && my_terminate_is_required == 0) {
 				while ((pthread_cond_wait(&my_cond_start_is_required, &my_mutex) == -1) && errno == EINTR)
 					continue; // Restart when interrupted by handler
 			}
 		}
 
-
 		my_command_is_running = 1;
 
 		assert(-1 != pthread_cond_broadcast(&my_cond_command_is_running));
 		assert(-1 != pthread_mutex_unlock(&my_mutex));
 
-		while (my_command_is_running) {
+		while (my_command_is_running && my_terminate_is_required == 0) {
 			int a_status = pthread_mutex_lock(&my_mutex);
 			assert(!a_status);
 			t_espeak_command *a_command = (t_espeak_command *)pop();
@@ -335,7 +335,7 @@ static void *say_thread(void *p)
 			}
 		}
 
-		if (my_stop_is_required) {
+		if (my_stop_is_required || my_terminate_is_required) {
 			// restart the audio early, to be more responsive when using eSpeak NG
 			// for audio.
 			close_audio();
@@ -440,8 +440,11 @@ static void init(int process_parameters)
 
 void fifo_terminate()
 {
-	pthread_cancel(my_thread);
+	my_terminate_is_required = 1;
+	pthread_cond_signal(&my_cond_start_is_required);
 	pthread_join(my_thread, NULL);
+	my_terminate_is_required = 0;
+
 	pthread_mutex_destroy(&my_mutex);
 	pthread_cond_destroy(&my_cond_start_is_required);
 	pthread_cond_destroy(&my_cond_stop_is_acknowledged);