source: trunk/third/yelp/src/yelp-reader.c @ 18397

Revision 18397, 17.9 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18396, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*
3 * Copyright (C) 2002 Mikael Hallendal <micke@codefactory.se>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 *
20 * Author: Mikael Hallendal <micke@codefactory.se>
21 */
22
23#include <libgnome/gnome-url.h>
24#include <libgnomevfs/gnome-vfs.h>
25#include <libxml/xmlIO.h>
26#include <libxslt/xslt.h>
27#include <libxslt/xsltInternals.h>
28#include <libxslt/transform.h>
29#include <libxslt/xsltutils.h>
30#include <string.h>
31
32#include "yelp-cache.h"
33#include "yelp-marshal.h"
34#include "yelp-reader.h"
35
36#define d(x)
37
38#define BUFFER_SIZE 16384
39
40#define STAMP_MUTEX_LOCK    g_mutex_lock(priv->stamp_mutex);
41#define STAMP_MUTEX_UNLOCK  g_mutex_unlock(priv->stamp_mutex);
42
43struct _YelpReaderPriv {
44        gint            stamp;
45
46        gboolean        active;
47
48        /* Locks */
49        GMutex         *stamp_mutex;
50        GAsyncQueue    *thread_queue;
51};
52
53typedef struct {
54        YelpReader *reader;
55        gint        stamp;
56        YelpURI    *uri;
57} ReaderThreadData;
58
59typedef enum {
60        READER_QUEUE_TYPE_START,
61        READER_QUEUE_TYPE_DATA,
62        READER_QUEUE_TYPE_CANCELLED,
63        READER_QUEUE_TYPE_FINISHED
64} ReaderQueueType;
65
66typedef struct {
67        YelpReader      *reader;
68        gint             stamp;
69        gchar           *data;
70        ReaderQueueType  type;
71} ReaderQueueData;
72
73static void      reader_class_init        (YelpReaderClass     *klass);
74static void      reader_init              (YelpReader          *reader);
75
76static void      reader_convert_start     (ReaderThreadData    *th_data);
77
78static void      reader_file_start        (ReaderThreadData    *th_data);
79
80static gboolean  reader_check_cancelled   (YelpReader          *reader,
81                                           gint                 stamp);
82static gpointer  reader_start             (ReaderThreadData    *th_data);
83static void      reader_change_stamp      (YelpReader          *reader);
84static gboolean  reader_idle_check_queue  (ReaderThreadData    *th_data);
85
86static ReaderQueueData *
87reader_q_data_new                         (YelpReader          *reader,
88                                           gint                 stamp,
89                                           ReaderQueueType      type);
90static void      reader_q_data_free       (ReaderQueueData     *q_data);
91
92#if 0
93/* FIXME: Solve this so we don't leak */
94static void      reader_th_data_free      (ReaderThreadData    *th_data);
95#endif
96static gchar *   reader_get_chunk         (const gchar         *document,
97                                           const gchar         *section);
98
99enum {
100        START,
101        DATA,
102        FINISHED,
103        CANCELLED,
104        ERROR,
105        LAST_SIGNAL
106};
107
108static gint signals[LAST_SIGNAL] = { 0 };
109
110GType
111yelp_reader_get_type (void)
112{
113        static GType type = 0;
114
115        if (!type) {
116                static const GTypeInfo info =
117                        {
118                                sizeof (YelpReaderClass),
119                                NULL,
120                                NULL,
121                                (GClassInitFunc) reader_class_init,
122                                NULL,
123                                NULL,
124                                sizeof (YelpReader),
125                                0,
126                                (GInstanceInitFunc) reader_init,
127                        };
128               
129                type = g_type_register_static (G_TYPE_OBJECT,
130                                               "YelpReader",
131                                               &info, 0);
132        }
133       
134        return type;
135}
136
137static void
138reader_class_init (YelpReaderClass *klass)
139{
140        signals[START] =
141                g_signal_new ("start",
142                              G_TYPE_FROM_CLASS (klass),
143                              G_SIGNAL_RUN_LAST,
144                              G_STRUCT_OFFSET (YelpReaderClass,
145                                               start),
146                              NULL, NULL,
147                              yelp_marshal_VOID__VOID,
148                              G_TYPE_NONE,
149                              0);
150
151        signals[DATA] =
152                g_signal_new ("data",
153                              G_TYPE_FROM_CLASS (klass),
154                              G_SIGNAL_RUN_LAST,
155                              G_STRUCT_OFFSET (YelpReaderClass,
156                                               data),
157                              NULL, NULL,
158                              yelp_marshal_VOID__STRING_INT,
159                              G_TYPE_NONE,
160                              2, G_TYPE_STRING, G_TYPE_INT);
161
162        signals[FINISHED] =
163                g_signal_new ("finished",
164                              G_TYPE_FROM_CLASS (klass),
165                              G_SIGNAL_RUN_LAST,
166                              G_STRUCT_OFFSET (YelpReaderClass,
167                                               finished),
168                              NULL, NULL,
169                              yelp_marshal_VOID__POINTER,
170                              G_TYPE_NONE,
171                              1, G_TYPE_POINTER);
172        signals[CANCELLED] =
173                g_signal_new ("cancelled",
174                              G_TYPE_FROM_CLASS (klass),
175                              G_SIGNAL_RUN_LAST,
176                              G_STRUCT_OFFSET (YelpReaderClass,
177                                               cancelled),
178                              NULL, NULL,
179                              yelp_marshal_VOID__VOID,
180                              G_TYPE_NONE,
181                              0);
182        signals[ERROR] =
183                g_signal_new ("error",
184                              G_TYPE_FROM_CLASS (klass),
185                              G_SIGNAL_RUN_LAST,
186                              G_STRUCT_OFFSET (YelpReaderClass,
187                                               error),
188                              NULL, NULL,
189                              yelp_marshal_VOID__POINTER,
190                              G_TYPE_NONE,
191                              1, G_TYPE_POINTER);
192}
193
194static void
195reader_init (YelpReader *reader)
196{
197        YelpReaderPriv *priv;
198       
199        priv = g_new0 (YelpReaderPriv, 1);
200        reader->priv = priv;
201       
202        priv->active       = FALSE;
203        priv->stamp        = 0;
204        priv->stamp_mutex  = g_mutex_new ();
205        priv->thread_queue = g_async_queue_new ();
206}
207
208static void
209reader_convert_start (ReaderThreadData *th_data)
210{
211        YelpReader      *reader;
212        YelpReaderPriv  *priv;
213        YelpURI         *uri;
214        gchar           *command_line = NULL;
215        GError          *error = NULL;
216        gint             exit_status;
217        ReaderQueueData *q_data;
218        gint             stamp;
219       
220        g_return_if_fail (th_data != NULL);
221
222        reader = th_data->reader;
223        priv   = reader->priv;
224        uri    = th_data->uri;
225        stamp  = th_data->stamp;
226       
227        d(g_print ("convert_start\n"));
228
229        STAMP_MUTEX_LOCK;
230       
231        if (reader_check_cancelled (reader, th_data->stamp)) {
232               
233                STAMP_MUTEX_UNLOCK;
234               
235                return;
236        }
237
238        STAMP_MUTEX_UNLOCK;
239
240        switch (yelp_uri_get_type (uri)) {
241        case YELP_URI_TYPE_MAN:
242                command_line = g_strdup_printf ("%s %s",
243                                                LIBGNOME_MAN2HTML,
244                                                yelp_uri_get_path (uri));
245                break;
246        case YELP_URI_TYPE_INFO:
247                if (yelp_uri_get_section (uri)) {
248                        command_line =
249                                g_strdup_printf ("%s %s?%s",
250                                                 LIBGNOME_INFO2HTML,
251                                                 yelp_uri_get_path (uri),
252                                                 yelp_uri_get_section (uri));
253                } else {
254                        command_line =
255                                g_strdup_printf ("%s %s",
256                                                 LIBGNOME_INFO2HTML,
257                                                 yelp_uri_get_path (uri));
258                }
259               
260                break;
261        case YELP_URI_TYPE_DOCBOOK_XML:
262        case YELP_URI_TYPE_DOCBOOK_SGML:
263                command_line = g_strdup_printf ("%s/yelp-db2html %s",
264                                                SERVERDIR,
265                                                yelp_uri_get_path (uri));
266                break;
267        default:
268                /* Set error */
269                break;
270        }
271
272        q_data = reader_q_data_new (reader, priv->stamp,
273                                    READER_QUEUE_TYPE_START);
274       
275        g_async_queue_push (priv->thread_queue, q_data);
276
277        q_data = reader_q_data_new (reader, priv->stamp,
278                                    READER_QUEUE_TYPE_DATA);
279
280        g_spawn_command_line_sync (command_line,
281                                   &q_data->data,
282                                   NULL,
283                                   &exit_status,
284                                   &error /* FIXME */);
285        if (yelp_uri_get_type (uri) == YELP_URI_TYPE_DOCBOOK_XML ||
286            yelp_uri_get_type (uri) == YELP_URI_TYPE_DOCBOOK_SGML) {
287                 yelp_cache_add (yelp_uri_get_path (uri), q_data->data);
288        }
289
290        g_free (command_line);
291
292        STAMP_MUTEX_LOCK;
293
294        if (reader_check_cancelled (reader, stamp)) {
295               
296                STAMP_MUTEX_UNLOCK;
297
298                reader_q_data_free (q_data);
299               
300                return;
301        }
302       
303        STAMP_MUTEX_UNLOCK;
304
305        if (error) {
306                /* FIXME: Don't do this */
307                g_signal_emit (reader, signals[ERROR], 0, error);
308                g_error_free (error);
309        } else {
310                if (yelp_uri_get_type (uri) == YELP_URI_TYPE_DOCBOOK_XML ||
311                    yelp_uri_get_type (uri) == YELP_URI_TYPE_DOCBOOK_SGML) {
312                        gchar *chunk;
313                       
314                        if (yelp_uri_get_section (uri) &&
315                            strcmp (yelp_uri_get_section (uri), "")) {
316                                chunk = reader_get_chunk (q_data->data,
317                                                          yelp_uri_get_section (uri));
318                        } else {
319                                chunk = reader_get_chunk (q_data->data,
320                                                          "toc");
321                        }
322
323                        g_free (q_data->data);
324                        q_data->data = chunk;
325
326                        if (!q_data->data) {
327                                q_data->data = g_strdup ("<html><body></body></html>");
328                        }
329                }
330               
331                g_async_queue_push (priv->thread_queue, q_data);
332                       
333                q_data = reader_q_data_new (reader, priv->stamp,
334                                            READER_QUEUE_TYPE_FINISHED);
335
336                g_async_queue_push (priv->thread_queue, q_data);
337        }
338}
339
340static void
341reader_file_start (ReaderThreadData *th_data)
342{
343        YelpReader       *reader;
344        YelpReaderPriv   *priv;
345        YelpURI          *uri;
346        gint              stamp;
347        GnomeVFSHandle   *handle;
348        GnomeVFSResult    result;
349        ReaderQueueData  *q_data;
350        gchar             buffer[BUFFER_SIZE];
351        GnomeVFSFileSize  n;
352       
353        g_return_if_fail (th_data != NULL);
354
355        reader = th_data->reader;
356        priv   = reader->priv;
357        uri    = th_data->uri;
358        stamp  = th_data->stamp;
359       
360        d(g_print ("file_start\n"));
361
362        STAMP_MUTEX_LOCK;
363       
364        if (reader_check_cancelled (reader, stamp)) {
365               
366                STAMP_MUTEX_UNLOCK;
367
368                return;
369        }
370
371        STAMP_MUTEX_UNLOCK;
372
373        result = gnome_vfs_open (&handle,
374                                 yelp_uri_get_path (uri),
375                                 GNOME_VFS_OPEN_READ);
376       
377        if (result != GNOME_VFS_OK) {
378                /* FIXME: Signal error */
379                return;
380        }
381
382        while (TRUE) {
383                result = gnome_vfs_read (handle, buffer, BUFFER_SIZE, &n);
384               
385                /* FIXME: Do some error checking */
386                if (result != GNOME_VFS_OK) {
387                        break;
388                }
389               
390                q_data = reader_q_data_new (reader, stamp,
391                                            READER_QUEUE_TYPE_DATA);
392                q_data->data = g_strdup (buffer);
393               
394                g_async_queue_push (priv->thread_queue, q_data);
395
396                STAMP_MUTEX_LOCK;
397               
398                if (reader_check_cancelled (reader, stamp)) {
399               
400                        STAMP_MUTEX_UNLOCK;
401
402                        return;
403                }
404               
405                STAMP_MUTEX_UNLOCK;
406        }
407
408        q_data = reader_q_data_new (reader, stamp, READER_QUEUE_TYPE_FINISHED);
409
410        g_async_queue_push (priv->thread_queue, q_data);
411}
412
413static gboolean
414reader_check_cancelled (YelpReader *reader, gint stamp)
415{
416        YelpReaderPriv *priv;
417       
418        g_return_val_if_fail (YELP_IS_READER (reader), TRUE);
419       
420        priv = reader->priv;
421
422        d(g_print ("check_cancelled\n"));
423       
424        if (priv->stamp != stamp) {
425                return TRUE;
426        }
427       
428        return FALSE;
429}
430
431static gpointer
432reader_start (ReaderThreadData *th_data)
433{
434        YelpReader         *reader;
435        YelpReaderPriv     *priv;
436        YelpURI            *uri;
437       
438        g_return_val_if_fail (th_data != NULL, NULL);
439
440        reader = th_data->reader;
441        priv   = reader->priv;
442        uri    = th_data->uri;
443       
444        d(g_print ("reader_start\n"));
445
446        if (!yelp_uri_exists (uri)) {
447                return NULL;
448        }
449
450        STAMP_MUTEX_LOCK;
451       
452        if (reader_check_cancelled (reader, th_data->stamp)) {
453                STAMP_MUTEX_UNLOCK;
454
455                /* FIXME: refs??? */
456/*              reader_th_data_free(th_data); */
457
458                return NULL;
459        }
460
461        if (priv->active) {
462                reader_change_stamp (reader);
463        }
464
465        STAMP_MUTEX_UNLOCK;
466       
467        switch (yelp_uri_get_type (uri)) {
468/*              reader_db_start (th_data); */
469/*              break; */
470        case YELP_URI_TYPE_DOCBOOK_XML:
471        case YELP_URI_TYPE_DOCBOOK_SGML:
472        case YELP_URI_TYPE_MAN:
473        case YELP_URI_TYPE_INFO:
474                reader_convert_start (th_data);
475                break;
476        case YELP_URI_TYPE_HTML:
477                reader_file_start (th_data);
478                break;
479        case YELP_URI_TYPE_TOC:
480                /* Should this be handled here?? */
481                break;
482        case YELP_URI_TYPE_INDEX:
483        case YELP_URI_TYPE_PATH:
484                /* Hmm .. is this wrong or what?? */
485                break;
486        default:
487                g_assert_not_reached ();
488               
489                break;
490        }
491
492        return NULL;
493}
494
495static void
496reader_change_stamp (YelpReader *reader)
497{
498        YelpReaderPriv *priv;
499       
500        g_return_if_fail (YELP_IS_READER (reader));
501       
502        priv = reader->priv;
503
504        if ((priv->stamp++) >= G_MAXINT) {
505                priv->stamp = 1;
506        }
507}
508
509static gboolean
510reader_idle_check_queue (ReaderThreadData *th_data)
511{
512        YelpReader      *reader;
513        YelpReaderPriv  *priv;
514        ReaderQueueData *q_data;
515        gboolean         ret_val = TRUE;
516       
517        g_return_val_if_fail (th_data != NULL, FALSE);
518
519        reader = th_data->reader;
520        priv   = reader->priv;
521       
522        if (!g_mutex_trylock (priv->stamp_mutex)) {
523                return TRUE;
524        }
525
526        if (th_data->stamp != priv->stamp) {
527                STAMP_MUTEX_UNLOCK;
528       
529/*              reader_th_data_free (th_data); */
530
531                return FALSE;
532        }
533
534        d(g_print ("Poping from queue... "));
535        q_data = (ReaderQueueData *)
536                g_async_queue_try_pop (priv->thread_queue);
537        d(g_print ("done\n"));
538       
539        if (q_data) {
540                if (priv->stamp != q_data->stamp) {
541                        /* Some old data */
542                        reader_q_data_free (q_data);
543                        ret_val = TRUE;
544
545                        q_data = NULL;
546                }
547        }
548       
549        if (q_data) {
550                switch (q_data->type) {
551                case READER_QUEUE_TYPE_START:
552                        g_signal_emit (reader, signals[START], 0);
553                        ret_val = TRUE;
554                        break;
555                case READER_QUEUE_TYPE_DATA:
556                        d(g_print ("queue_type_data\n"));
557                       
558                        if (q_data->data != NULL) {
559                                g_signal_emit (reader, signals[DATA], 0,
560                                               q_data->data, -1);
561                        }
562                        ret_val = TRUE;
563                        break;
564                case READER_QUEUE_TYPE_CANCELLED:
565                        priv->active = FALSE;
566
567                        if ((priv->stamp++) >= G_MAXINT) {
568                                priv->stamp = 1;
569                        }
570
571                        g_signal_emit (reader, signals[CANCELLED], 0);
572
573                        ret_val = FALSE;
574                        break;
575                case READER_QUEUE_TYPE_FINISHED:
576                        priv->active = FALSE;
577
578                        d(g_print ("queue_type_finished\n"));
579                       
580                        if ((priv->stamp++) >= G_MAXINT) {
581                                priv->stamp = 1;
582                        }
583
584                        g_signal_emit (reader, signals[FINISHED], 0,
585                                       th_data->uri);
586
587                        ret_val = FALSE;
588                        break;
589                default:
590                        g_assert_not_reached ();
591                }
592
593                reader_q_data_free (q_data);
594        }
595
596        STAMP_MUTEX_UNLOCK;
597                       
598        return ret_val;
599}
600
601static ReaderQueueData *
602reader_q_data_new (YelpReader *reader, gint stamp, ReaderQueueType type)
603{
604        ReaderQueueData *q_data;
605       
606        q_data = g_new0 (ReaderQueueData, 1);
607        q_data->reader = g_object_ref (reader);
608        q_data->stamp  = stamp;
609        q_data->type   = type;
610        q_data->data   = NULL;
611
612        return q_data;
613}
614
615static void
616reader_q_data_free (ReaderQueueData *q_data)
617{
618        g_return_if_fail (q_data != NULL);
619       
620        g_object_unref (q_data->reader);
621        g_free (q_data->data);
622        g_free (q_data);
623}
624
625#if 0
626static void
627reader_th_data_free (ReaderThreadData *th_data)
628{
629        g_return_if_fail (th_data != NULL);
630       
631        g_object_unref (th_data->reader);
632        yelp_uri_unref (th_data->uri);
633       
634        g_free (th_data);
635}
636#endif
637
638static gchar *
639reader_get_chunk (const gchar *document, const gchar *section)
640{
641        gchar       *header;
642        gchar       *chunk;
643        const gchar *footer;
644        gchar       *ret_val;
645        const gchar *start;
646        const gchar *end;
647        gchar       *tag;
648        GTimer      *timer;
649       
650/*      g_print ("%s\n", document); */
651
652        timer = g_timer_new ();
653
654        end = strstr (document, "<!-- End of header -->");
655       
656        if (!end) {
657/*              g_warning ("Wrong type of document\n"); */
658                return g_strdup (document);
659        }
660       
661        header = g_strndup (document, end - document);
662       
663        tag = g_strdup_printf ("<!-- Start of chunk: [%s] -->", section);
664        start = strstr (document, tag);
665        g_free (tag);
666       
667        if (!start) {
668/*              g_warning ("Document doesn't include section: '%s'", section); */
669                g_free (header);
670
671                return g_strdup (document);
672        }
673
674        end = strstr (start, "<!-- End of chunk -->");
675
676        if (!end) {
677/*              g_warning ("Document is doesn't contain end tag for section: %s", */
678/*                         section); */
679                g_free (header);
680
681                return g_strdup (document);
682        }
683       
684        chunk = g_strndup (start, end - start);
685       
686        footer = strstr (document, "<!-- Start of footer -->");
687       
688        if (!footer) {
689/*              g_warning ("Couldn't find footer in document"); */
690                g_free (header);
691                g_free (chunk);
692
693                return g_strdup (document);
694        }
695         
696        ret_val = g_strconcat (header, chunk, footer, NULL);
697       
698        g_free (header);
699        g_free (chunk);
700
701/*      g_print ("Finding chunk took: %f seconds\n",  */
702/*               g_timer_elapsed (timer, 0)); */
703
704        return ret_val;
705}
706
707YelpReader *
708yelp_reader_new ()
709{
710        YelpReader     *reader;
711        YelpReaderPriv *priv;
712       
713        reader = g_object_new (YELP_TYPE_READER, NULL);
714       
715        priv = reader->priv;
716       
717        return reader;
718}
719
720gboolean
721yelp_reader_start (YelpReader *reader, YelpURI *uri)
722{
723        YelpReaderPriv   *priv;
724        ReaderThreadData *th_data;
725        gint              stamp;
726        gchar              *str_uri;
727
728        g_return_val_if_fail (YELP_IS_READER (reader), FALSE);
729        g_return_val_if_fail (uri != NULL, FALSE);
730
731        priv = reader->priv;
732
733        d(g_print ("yelp_reader_start\n"));
734
735        STAMP_MUTEX_LOCK;
736       
737        if (priv->active) {
738                reader_change_stamp (reader);
739        }
740       
741        stamp = priv->stamp;
742
743        STAMP_MUTEX_UNLOCK;
744
745        th_data = g_new0 (ReaderThreadData, 1);
746        th_data->reader = g_object_ref (reader);
747        th_data->uri    = yelp_uri_ref (uri);
748        th_data->stamp  = stamp;
749
750        if (yelp_uri_get_type (uri) == YELP_URI_TYPE_FILE ||
751            yelp_uri_get_type (uri) == YELP_URI_TYPE_UNKNOWN ||
752            yelp_uri_get_type (uri) == YELP_URI_TYPE_GHELP_OTHER) {
753                gboolean ret_val;
754               
755                str_uri = yelp_uri_to_string (uri);
756                ret_val = gnome_url_show (str_uri, NULL);
757                g_free (str_uri);
758
759                return ret_val;
760        }
761
762        if (yelp_uri_get_type (uri) == YELP_URI_TYPE_DOCBOOK_XML ||
763            yelp_uri_get_type (uri) == YELP_URI_TYPE_DOCBOOK_SGML) {
764                const gchar *document;
765                gchar *chunk;
766
767                document = yelp_cache_lookup (yelp_uri_get_path (uri));
768               
769                if (document) {
770                        if (yelp_uri_get_section (uri) &&
771                            strcmp (yelp_uri_get_section (uri), "")) {
772                                chunk = reader_get_chunk (document,
773                                                          yelp_uri_get_section (uri));
774                        } else {
775                                chunk = reader_get_chunk (document, "toc");
776                        }
777               
778                        if (chunk) {
779                                ReaderQueueData *q_data;
780                               
781                                q_data = reader_q_data_new (reader, stamp,
782                                                            READER_QUEUE_TYPE_START);
783                                g_async_queue_push (priv->thread_queue,
784                                                    q_data);
785
786                                q_data = reader_q_data_new (reader, stamp,
787                                                            READER_QUEUE_TYPE_DATA);
788
789                                q_data->data = chunk;
790                                g_async_queue_push (priv->thread_queue,
791                                                    q_data);
792                               
793                                q_data = reader_q_data_new (reader, stamp,
794                                                            READER_QUEUE_TYPE_FINISHED);
795
796                                g_async_queue_push (priv->thread_queue,
797                                                    q_data);
798
799                                g_idle_add ((GSourceFunc) reader_idle_check_queue, th_data);
800                                return TRUE;
801                        }
802                }
803        }
804       
805        g_timeout_add (100, (GSourceFunc) reader_idle_check_queue, th_data);
806
807        g_thread_create_full ((GThreadFunc) reader_start, th_data,
808                              2 * BUFFER_SIZE,
809                              TRUE,
810                              FALSE, G_THREAD_PRIORITY_NORMAL,
811                              NULL /* FIXME: check for errors */);
812        return FALSE;
813}
814
815void
816yelp_reader_cancel (YelpReader *reader)
817{
818        YelpReaderPriv *priv;
819       
820        g_return_if_fail (YELP_IS_READER (reader));
821       
822        priv = reader->priv;
823
824        STAMP_MUTEX_LOCK;
825       
826        reader_change_stamp (reader);
827
828        STAMP_MUTEX_UNLOCK;
829}
Note: See TracBrowser for help on using the repository browser.