Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@member.fsf.org>2009-03-08 05:59:36 (GMT)
committer Aleksey Lim <alsroot@member.fsf.org>2009-03-08 05:59:36 (GMT)
commit5f8e048768a4bec23e5770d7334c29bfb76ed726 (patch)
treebcfb89887d3b0ac8722eaf3b20d91816e2bec5ca
parentcb29c2846e1b4157f2cac9ef5db6f67f1898d0bf (diff)
Fix poping from in_queue
-rw-r--r--src/espeak.c76
-rw-r--r--src/slist.h84
-rw-r--r--src/text.h7
3 files changed, 128 insertions, 39 deletions
diff --git a/src/espeak.c b/src/espeak.c
index 63c11e6..2457769 100644
--- a/src/espeak.c
+++ b/src/espeak.c
@@ -29,6 +29,7 @@
#include "espeak.h"
#include "text.h"
+#include "slist.h"
typedef enum
{
@@ -66,7 +67,8 @@ struct _Econtext
Espin *process;
Espin *out;
- GSList *in_queue;
+ SList in_queue;
+
GSList *process_chunk;
volatile gint rate;
@@ -133,6 +135,8 @@ espeak_new(GstElement *emitter)
self->process = self->queue;
self->out = self->queue;
+ slist_new(&self->in_queue);
+
self->process_chunk = g_slist_alloc();
self->process_chunk->data = self;
@@ -142,7 +146,6 @@ espeak_new(GstElement *emitter)
self->emitter = emitter;
gst_object_ref(self->emitter);
-
self->bus = NULL;
GST_DEBUG("[%p]", self);
@@ -168,14 +171,7 @@ espeak_unref(Econtext *self)
g_array_free(self->queue[i].events, TRUE);
}
- if (self->in_queue)
- {
- GSList *i;
- for (i = self->in_queue; i; i = g_slist_next(i))
- text_unref(i->data);
- g_slist_free(self->in_queue);
- }
-
+ slist_free(&self->in_queue);
g_slist_free(self->process_chunk);
gst_object_unref(self->bus);
@@ -188,20 +184,22 @@ espeak_unref(Econtext *self)
// in/out ----------------------------------------------------------------------
static void
-in_spinning(Econtext *self, Text *text)
+in_spinning(Econtext *self, Espin **spin, Text *text)
{
GST_DEBUG("[%p] text.body=%s text.offset=%ld text.frame_len=%ld",
self, text->body, text->offset, text->frame_len);
gboolean chunked = FALSE;
- while (!text_eot(text) && g_atomic_int_get(&self->in->state) == IN)
+ while (!text_eot(text))
{
- Espin *spin = self->in;
- text_chunk(text, &spin->text, SPIN_FRAME_SIZE);
- g_atomic_int_set(&spin->state, PROCESS);
- spinning(self->queue, &self->in);
+ text_chunk(text, &(*spin)->text, SPIN_FRAME_SIZE);
+ g_atomic_int_set(&(*spin)->state, PROCESS);
+ spinning(self->queue, spin);
chunked = TRUE;
+
+ if (g_atomic_int_get(&(*spin)->state) != IN)
+ break;
}
if (chunked)
@@ -221,18 +219,19 @@ espeak_in(Econtext *self, const gchar *str_)
Text *text = text_new(str_);
- if (self->in_queue)
+ if (g_atomic_int_get(&self->in->state) != IN)
{
- self->in_queue = g_slist_append(self->in_queue, text);
+ // in_queue should be not empty at this point
+ slist_push(&self->in_queue, text);
return;
}
- in_spinning(self, text);
+ in_spinning(self, &self->in, text);
if (!text_eot(text))
{
GST_DEBUG("[%p] text_len=%d", self, text_len(text));
- self->in_queue = g_slist_append(self->in_queue, text);
+ slist_push(&self->in_queue, text);
}
}
@@ -330,7 +329,8 @@ espeak_out(Econtext *self, gsize size_to_play)
g_mutex_lock(process_lock);
while ((g_atomic_int_get(&self->out->state) & (PLAY|OUT)) == 0)
{
- if ((self->state & INPROCESS) == 0)
+ if ((self->state & INPROCESS) == 0 &&
+ slist_empty(&self->in_queue))
{
GST_DEBUG("[%p]", self);
g_mutex_unlock(process_lock);
@@ -344,31 +344,35 @@ espeak_out(Econtext *self, gsize size_to_play)
Espin *spin = self->out;
gsize spin_size = g_memory_output_stream_get_data_size(spin->sound);
- GST_DEBUG("[%p] spin->sound_offset=%ld spin_size=%ld", self,
- spin->sound_offset, spin_size);
+ GST_DEBUG("[%p] spin->sound_offset=%ld spin_size=%ld spin->body=%s",
+ self, spin->sound_offset, spin_size,
+ spin->text.body + spin->text.frame_len);
if (g_atomic_int_get(&spin->state) == PLAY &&
spin->sound_offset >= spin_size)
{
- g_atomic_int_set(&spin->state, IN);
text_unref(&spin->text);
- spinning(self->queue, &self->out);
- if (self->in_queue)
+ GSList *text_link = slist_pop_link(&self->in_queue);
+
+ if (text_link)
{
- Text *text = self->in_queue->data;
- in_spinning(self, text);
+ Text *text = text_link->data;
+ in_spinning(self, &self->out, text);
+
+ GST_DEBUG("[%p] text_eot=%d", self, text_eot(text));
if (text_eot(text))
- {
- self->in_queue = g_slist_delete_link(self->in_queue,
- self->in_queue);
- GST_DEBUG("[%p] in_queue=%d", self,
- g_slist_length(self->in_queue));
- }
+ g_slist_free(text_link);
+ else
+ slist_push_link(&self->in_queue, text_link);
+ }
+ else
+ {
+ GST_DEBUG("[%p]", self);
+ g_atomic_int_set(&spin->state, IN);
+ spinning(self->queue, &self->out);
}
-
- GST_DEBUG("[%p]", self);
continue;
}
diff --git a/src/slist.h b/src/slist.h
new file mode 100644
index 0000000..f7c7ae9
--- /dev/null
+++ b/src/slist.h
@@ -0,0 +1,84 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef SLIST_H
+#define SLIST_H
+
+typedef struct
+{
+ GSList *list;
+ GMutex *lock;
+} SList;
+
+inline void
+slist_new(SList *self)
+{
+ self->list = NULL;
+ self->lock = g_mutex_new();
+}
+
+inline void
+slist_free(SList *self)
+{
+ GSList *i;
+
+ for (i = self->list; i; i = g_slist_next(i))
+ text_unref(i->data);
+
+ g_slist_free(self->list);
+ g_mutex_free(self->lock);
+}
+
+inline gboolean
+slist_empty(SList *self)
+{
+ g_mutex_lock(self->lock);
+ gboolean out = self->list == NULL;
+ g_mutex_unlock(self->lock);
+ return out;
+}
+
+inline GSList*
+slist_pop_link(SList *self)
+{
+ GSList *out = NULL;
+
+ g_mutex_lock(self->lock);
+ out = self->list;
+ self->list = g_slist_remove_link(self->list, self->list);
+ g_mutex_unlock(self->lock);
+
+ return out;
+}
+
+inline void
+slist_push(SList *self, Text *data)
+{
+ g_mutex_lock(self->lock);
+ self->list = g_slist_append(self->list, data);
+ g_mutex_unlock(self->lock);
+}
+
+inline void
+slist_push_link(SList *self, GSList *link)
+{
+ g_mutex_lock(self->lock);
+ self->list = g_slist_concat(link, self->list);
+ g_mutex_unlock(self->lock);
+}
+
+#endif
diff --git a/src/text.h b/src/text.h
index 0a83985..0e65e18 100644
--- a/src/text.h
+++ b/src/text.h
@@ -76,9 +76,10 @@ text_chunk(Text *src, Text *dst, gsize len)
src->offset += dst->frame_len;
src->frame_len -= dst->frame_len;
- GST_DEBUG("[%p] len=%ld dst_len=%ld dst_last=%ld "
- "src->offset=%ld src->frame_len=%ld", src, len, dst_len,
- dst_last-dst->body, src->offset, src->frame_len);
+ GST_DEBUG("[%p] dst_len=%ld dst_last=%ld "
+ "src->offset=%ld src->frame_len=%ld dst->body=%s", src, dst_len,
+ dst_last-dst->body, src->offset, src->frame_len,
+ dst->body + dst->offset);
}
inline gchar*