Blame platform-demos/el/custom-gsource.c.page

Packit 1470ea
Packit 1470ea
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" xmlns:xi="http://www.w3.org/2003/XInclude" type="guide" style="task" id="custom-gsource.c" xml:lang="el">
Packit 1470ea
Packit 1470ea
  <info>
Packit 1470ea
    <link type="guide" xref="c#examples"/>
Packit 1470ea
Packit 1470ea
    <credit type="author copyright">
Packit 1470ea
      <name>Philip Withnall</name>
Packit 1470ea
      <email its:translate="no">philip.withnall@collabora.co.uk</email>
Packit 1470ea
      <years>2015</years>
Packit 1470ea
    </credit>
Packit 1470ea
Packit 1470ea
    <include xmlns="http://www.w3.org/2001/XInclude" href="legal.xml"/>
Packit 1470ea
Packit 1470ea
    <desc>Μάθημα για την εγγραφή μιας προσαρμοσμένης υλοποίησης GSource</desc>
Packit 1470ea
  
Packit 1470ea
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
Packit 1470ea
      <mal:name>Ελληνική μεταφραστική ομάδα GNOME</mal:name>
Packit 1470ea
      <mal:email>team@gnome.gr</mal:email>
Packit 1470ea
      <mal:years>2012-2015</mal:years>
Packit 1470ea
    </mal:credit>
Packit 1470ea
  
Packit 1470ea
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
Packit 1470ea
      <mal:name>Δημήτρης Σπίγγος</mal:name>
Packit 1470ea
      <mal:email>dmtrs32@gmail.com</mal:email>
Packit 1470ea
      <mal:years>2012, 2013</mal:years>
Packit 1470ea
    </mal:credit>
Packit 1470ea
  
Packit 1470ea
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
Packit 1470ea
      <mal:name>Μαρία Θουκιδίδου</mal:name>
Packit 1470ea
      <mal:email>marablack3@gmail.com</mal:email>
Packit 1470ea
      <mal:years>2014</mal:years>
Packit 1470ea
    </mal:credit>
Packit 1470ea
  
Packit 1470ea
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
Packit 1470ea
      <mal:name>Θάνος Τρυφωνίδης</mal:name>
Packit 1470ea
      <mal:email>tomtryf@gmail.com</mal:email>
Packit 1470ea
      <mal:years>2014, 2015</mal:years>
Packit 1470ea
    </mal:credit>
Packit 1470ea
  </info>
Packit 1470ea
Packit 1470ea
  <title>Προσαρμοσμένα GSources</title>
Packit 1470ea
Packit 1470ea
  <synopsis>
Packit 1470ea
    <title>Περίληψη</title>
Packit 1470ea
Packit 1470ea
    

Αυτό το κείμενο είναι ένα μάθημα για την δημιουργία ενός προσαρμοσμένου GSource. Αν θέλετε να δείτε περισσότερη τεκμηρίωση, επισκεφθείτε την <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#GSource">αναφορά του GLib API</link>.

Packit 1470ea
  </synopsis>
Packit 1470ea
Packit 1470ea
  <section id="what-is-gsource">
Packit 1470ea
    <title>Τι είναι GSource;</title>
Packit 1470ea
Packit 1470ea
    

Το <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#GSource">GSource</link> είναι ένα γεγονός με μια συσχετισμένη συνάρτηση επανάκλησης η οποία καλείται όταν λαμβάνεται το γεγονός. Το γεγονός αυτό μπορεί να είναι ένα χρονικό όριο ή δεδομένα που λαμβάνονται από μια υποδοχή.

Packit 1470ea
Packit 1470ea
    

Το GLib περιλαμβάνει διάφορους τύπους GSource, αλλά επιτρέπει επίσης της εφαρμογές να ορίσουν τα δικά τους, επιτρέποντας προσαρμοσμένα συμβάντα να ενσωματωθούν στον κύριο βρόγχο του προγράμματος.

Packit 1470ea
Packit 1470ea
    

Η δομή του GSource και των εικονικών συναρτήσεων περιγράφονται λεπτομερώς στην <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#GSourceFuncs">αναφορά του GLib API</link>.

Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="queue-source">
Packit 1470ea
    <title>Πηγή μιας ουράς μηνύματος</title>
Packit 1470ea
Packit 1470ea
    

Για παράδειγμα, η πηγή μιας ουράς μηνύματος θα χρησιμοποιηθεί για να σταλθεί η επανάκληση της κάθε φορά που ένα μήνυμα θα μπει στην ουρά της πηγής (συνήθως από άλλο νήμα).

Packit 1470ea
Packit 1470ea
    

Αυτός ο τύπος πηγής είναι χρήσιμος για την αποτελεσματική μεταφορά μεγάλου αριθμού μηνυμάτων. Ένας εναλλακτικός τρόπος είναι η μεταφορά κάθε μηνύματος ως ξεχωριστό GSource χρησιμοποιώντας το g_source_attach(). Για μεγάλο αριθμό μηνυμάτων, αυτό σημαίνει πως θα υπάρχουν πολλές λειτουργίες κατανομών και ελευθέρωσης των GSource.

Packit 1470ea
Packit 1470ea
    <section id="gsource-structure">
Packit 1470ea
      <title>Δομή</title>
Packit 1470ea
Packit 1470ea
      

Αρχικά, πρέπει να οριστεί μια δομή για τις ανάγκες του κώδικα. Αυτή η δομή πρέπει να περιέχει ένα GSource ως γονικό, ακολουθόμενο από ιδιωτικά πεδία: την ουρά και μια συνάρτηση για να καλεστεί κάθε μήνυμα όταν τελειώσει.

Packit 1470ea
      
Packit 1470ea
typedef struct {
Packit 1470ea
  GSource         parent;
Packit 1470ea
  GAsyncQueue    *queue;  /* owned */
Packit 1470ea
  GDestroyNotify  destroy_message;
Packit 1470ea
} MessageQueueSource;
Packit 1470ea
    </section>
Packit 1470ea
Packit 1470ea
    <section id="prepare-function">
Packit 1470ea
      <title>Συνάρτηση προετοιμασίας</title>
Packit 1470ea
Packit 1470ea
      

Στη συνέχεια, πρέπει να οριστεί η συνάρτηση προετοιμασίας. Αυτή καθορίζει αν ο κώδικας είναι έτοιμος να σταλθεί. Καθώς αυτός ο κώδικας χρησιμοποιεί μια ουρά μνήμης, η ενέργεια μπορεί να καθοριστεί ελέγχοντας το μήκος της ουράς: αν υπάρχουν στοιχεία στην ουρά, τότε ο κώδικας μπορεί να σταλθεί για να τα διαχειριστεί.

Packit 1470ea
      
Packit 1470ea
return (g_async_queue_length (message_queue_source->queue) > 0);
Packit 1470ea
    </section>
Packit 1470ea
Packit 1470ea
    <section id="check-function">
Packit 1470ea
      <title>Συνάρτηση ελέγχου</title>
Packit 1470ea
Packit 1470ea
      

Καθώς αυτή η πηγή δεν έχει καθόλου περιγραφείς αρχείων, οι συναρτήσεις προετοιμασίας και ελέγχου εκτελούν την ίδια δουλειά, έτσι δεν είναι αναγκαία μια συνάρτηση ελέγχου. Ορίζοντας το πεδίο σε NULL στο GSourceFuncs παρακάμπτεται η συνάρτηση ελέγχου για αυτόν τον τύπο πηγής.

Packit 1470ea
    </section>
Packit 1470ea
Packit 1470ea
    <section id="dispatch-function">
Packit 1470ea
      <title>Συνάρτηση αποστολής</title>
Packit 1470ea
Packit 1470ea
      

Η συνάρτηση αποστολής είναι το πιο πολύπλοκο κομμάτι. Πρέπει να πάρει ένα μήνυμα από την ουρά και να το περάσει στην συνάρτηση επανάκλησης του GSource. Δεν είναι απαραίτητο να υπάρχουν μηνύματα στην ουρά: ακόμα και αν η συνάρτηση προετοιμασίας επιστρέψει αληθές, μια άλλη πηγή μπορεί να έχει δεχτεί το τελικό μήνυμα από την ουρά. Επίσης, αν δεν είχε οριστεί μια συνάρτηση επανάκλησης για το GSource (το οποίο είναι αποδεκτό), το μήνυμα πρέπει να καταστραφεί.

Packit 1470ea
Packit 1470ea
      

Αν έχει οριστεί ένα μήνυμα και μια επανάκληση, η επανάκληση μπορεί να καλεστεί από το μήνυμα και να επιστρέψει μια τιμή, όπως η τιμή που επιστρέφεται από την συνάρτηση αποστολής. Αυτό ορίζεται ως FALSE για την καταστροφή του GSource και TRUE για να παραμείνει ως έχει, όπως και το GSourceFunc — αυτά παραμένουν τα ίδια για όλες τις υλοποιήσεις μιας συνάρτησης αποστολής.

Packit 1470ea
      
Packit 1470ea
/* Pop a message off the queue. */
Packit 1470ea
message = g_async_queue_try_pop (message_queue_source->queue);
Packit 1470ea
Packit 1470ea
/* If there was no message, bail. */
Packit 1470ea
if (message == NULL)
Packit 1470ea
  {
Packit 1470ea
    /* Keep the source around to handle the next message. */
Packit 1470ea
    return TRUE;
Packit 1470ea
  }
Packit 1470ea
Packit 1470ea
/* @func may be %NULL if no callback was specified.
Packit 1470ea
 * If so, drop the message. */
Packit 1470ea
if (func == NULL)
Packit 1470ea
  {
Packit 1470ea
    if (message_queue_source->destroy_message != NULL)
Packit 1470ea
      {
Packit 1470ea
        message_queue_source->destroy_message (message);
Packit 1470ea
      }
Packit 1470ea
Packit 1470ea
    /* Keep the source around to consume the next message. */
Packit 1470ea
    return TRUE;
Packit 1470ea
  }
Packit 1470ea
Packit 1470ea
return func (message, user_data);
Packit 1470ea
    </section>
Packit 1470ea
Packit 1470ea
    <section id="callback">
Packit 1470ea
      <title>Συναρτήσεις επανάκλησης</title>
Packit 1470ea
Packit 1470ea
      

Η επανάκληση από το GSource δεν είναι αναγκαίο να είναι τύπου GSourceFunc. Μπορεί να είναι οποιουδήποτε τύπου συνάρτηση στην πηγή της συνάρτησης επανάκλησης, εφόσον αυτός ο τύπος είναι επαρκώς τεκμηριωμένος.

Packit 1470ea
Packit 1470ea
      

Συνήθως, το g_source_set_callback() χρησιμοποιείται για να οριστεί η συνάρτηση επανάκλησης για ένα στιγμιότυπο πηγής. Με το GDestroyNotify του, μια ισχυρή αναφορά μπορεί να δημιουργηθεί για να κρατήσει ζωντανό το αντικείμενο καθώς η πηγή είναι ακόμα ενεργή:

Packit 1470ea
      
Packit 1470ea
g_source_set_callback (source, callback_func,
Packit 1470ea
                       g_object_ref (object_to_strong_ref),
Packit 1470ea
                       (GDestroyNotify) g_object_unref);
Packit 1470ea
Packit 1470ea
      

Ωστόσο, το GSource διαθέτει μια στρώση για τη ήψη της επανάκλησης, ως g_source_set_callback_indirect(). Αυτό επιτρέπει το GObject να ορίσει ένα GClosure ως επανάκληση για την πηγή, επιτρέποντας τις πηγές να καταστρέφονται αυτόματα όταν οριστοποιηθεί ένα αντικείμενο — μια χαλαρή αναφορά, σε αντίθεση με την ισχυρή αναφορά παραπάνω:

Packit 1470ea
      
Packit 1470ea
g_source_set_closure (source,
Packit 1470ea
                      g_cclosure_new_object (callback_func,
Packit 1470ea
                                             object_to_weak_ref));
Packit 1470ea
Packit 1470ea
      

Επιτρέπει επίσης για μια γενική, εικονική επανάκληση, η οποία μπορεί να χρησιμοποιηθεί όταν μια πηγή χρειάζεται να τερματιστεί αλλά δεν απαιτείται να εκτελεστούν ενέργειες στην επανάκληση της:

Packit 1470ea
      
Packit 1470ea
g_source_set_dummy_callback (source);
Packit 1470ea
    </section>
Packit 1470ea
Packit 1470ea
    <section id="constructor">
Packit 1470ea
      <title>Κατασκευαστής</title>
Packit 1470ea
Packit 1470ea
      

Τέλος, ο ορισμός του GSourceFuncs για το GSource μπορεί να γραφεί μαζί με μια συνάρτηση κατασκευαστή. Είναι κοινή πρακτική να παρουσιάζονται οι νέοι τύποι πηγών ως GSource, αλλά όχι ως τύπο της δομής, έτσι ώστε ο κατασκευαστής να επιστρέφει το GSource*.

Packit 1470ea
Packit 1470ea
      

Το παράδειγμα του κατασκευαστή παρουσιάζει τη χρήση μιας θυγατρικής πηγής για την υποστήριξη της λειτουργίας ακύρωσης. Αν ακυρωθεί το GCancellable, η επανάκλαση της εφαρμογής θα σταλθεί και θα ελέγξει για την ακύρωση. (Ο κώδικας της εφαρμογής θα πρέπει να δημιουργήσει έναν δείκτη στο GCancellable που θα είναι διαθέσιμο στην επανάκληση ως ένα πεδίο για τα δεδομένα του χρήστη στο g_source_set_callback()).

Packit 1470ea
      
Packit 1470ea
GSource *
Packit 1470ea
message_queue_source_new (GAsyncQueue    *queue,
Packit 1470ea
                          GDestroyNotify  destroy_message,
Packit 1470ea
                          GCancellable   *cancellable)
Packit 1470ea
{
Packit 1470ea
  GSource *source;  /* alias of @message_queue_source */
Packit 1470ea
  MessageQueueSource *message_queue_source;  /* alias of @source */
Packit 1470ea
Packit 1470ea
  g_return_val_if_fail (queue != NULL, NULL);
Packit 1470ea
  g_return_val_if_fail (cancellable == NULL ||
Packit 1470ea
                        G_IS_CANCELLABLE (cancellable), NULL);
Packit 1470ea
Packit 1470ea
  source = g_source_new (&message_queue_source_funcs,
Packit 1470ea
                         sizeof (MessageQueueSource));
Packit 1470ea
  message_queue_source = (MessageQueueSource *) source;
Packit 1470ea
Packit 1470ea
  /* The caller can overwrite this name with something more useful later. */
Packit 1470ea
  g_source_set_name (source, "MessageQueueSource");
Packit 1470ea
Packit 1470ea
  message_queue_source->queue = g_async_queue_ref (queue);
Packit 1470ea
  message_queue_source->destroy_message = destroy_message;
Packit 1470ea
Packit 1470ea
  /* Add a cancellable source. */
Packit 1470ea
  if (cancellable != NULL)
Packit 1470ea
    {
Packit 1470ea
      GSource *cancellable_source;
Packit 1470ea
Packit 1470ea
      cancellable_source = g_cancellable_source_new (cancellable);
Packit 1470ea
      g_source_set_dummy_callback (cancellable_source);
Packit 1470ea
      g_source_add_child_source (source, cancellable_source);
Packit 1470ea
      g_source_unref (cancellable_source);
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
  return source;
Packit 1470ea
}
Packit 1470ea
    </section>
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="full-listing">
Packit 1470ea
    <title>Πλήρες παράδειγμα</title>
Packit 1470ea
Packit 1470ea
    <listing>
Packit 1470ea
      <title>Δείγμα πλήρους κώδικα</title>
Packit 1470ea
Packit 1470ea
      /**
Packit 1470ea
 * MessageQueueSource:
Packit 1470ea
 *
Packit 1470ea
 * This is a #GSource which wraps a #GAsyncQueue and is dispatched whenever a
Packit 1470ea
 * message can be pulled off the queue. Messages can be enqueued from any
Packit 1470ea
 * thread.
Packit 1470ea
 *
Packit 1470ea
 * The callbacks dispatched by a #MessageQueueSource have type
Packit 1470ea
 * #MessageQueueSourceFunc.
Packit 1470ea
 *
Packit 1470ea
 * #MessageQueueSource supports adding a #GCancellable child source which will
Packit 1470ea
 * additionally dispatch if a provided #GCancellable is cancelled.
Packit 1470ea
 */
Packit 1470ea
typedef struct {
Packit 1470ea
  GSource         parent;
Packit 1470ea
  GAsyncQueue    *queue;  /* owned */
Packit 1470ea
  GDestroyNotify  destroy_message;
Packit 1470ea
} MessageQueueSource;
Packit 1470ea
Packit 1470ea
/**
Packit 1470ea
 * MessageQueueSourceFunc:
Packit 1470ea
 * @message: (transfer full) (nullable): message pulled off the queue
Packit 1470ea
 * @user_data: user data provided to g_source_set_callback()
Packit 1470ea
 *
Packit 1470ea
 * Callback function type for #MessageQueueSource.
Packit 1470ea
 */
Packit 1470ea
typedef gboolean (*MessageQueueSourceFunc) (gpointer message,
Packit 1470ea
                                            gpointer user_data);
Packit 1470ea
Packit 1470ea
static gboolean
Packit 1470ea
message_queue_source_prepare (GSource *source,
Packit 1470ea
                              gint    *timeout_)
Packit 1470ea
{
Packit 1470ea
  MessageQueueSource *message_queue_source = (MessageQueueSource *) source;
Packit 1470ea
Packit 1470ea
  return (g_async_queue_length (message_queue_source->queue) > 0);
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
static gboolean
Packit 1470ea
message_queue_source_dispatch (GSource     *source,
Packit 1470ea
                               GSourceFunc  callback,
Packit 1470ea
                               gpointer     user_data)
Packit 1470ea
{
Packit 1470ea
  MessageQueueSource *message_queue_source = (MessageQueueSource *) source;
Packit 1470ea
  gpointer message;
Packit 1470ea
  MessageQueueSourceFunc func = (MessageQueueSourceFunc) callback;
Packit 1470ea
Packit 1470ea
  /* Pop a message off the queue. */
Packit 1470ea
  message = g_async_queue_try_pop (message_queue_source->queue);
Packit 1470ea
Packit 1470ea
  /* If there was no message, bail. */
Packit 1470ea
  if (message == NULL)
Packit 1470ea
    {
Packit 1470ea
      /* Keep the source around to handle the next message. */
Packit 1470ea
      return TRUE;
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
  /* @func may be %NULL if no callback was specified.
Packit 1470ea
   * If so, drop the message. */
Packit 1470ea
  if (func == NULL)
Packit 1470ea
    {
Packit 1470ea
      if (message_queue_source->destroy_message != NULL)
Packit 1470ea
        {
Packit 1470ea
          message_queue_source->destroy_message (message);
Packit 1470ea
        }
Packit 1470ea
Packit 1470ea
      /* Keep the source around to consume the next message. */
Packit 1470ea
      return TRUE;
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
  return func (message, user_data);
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
static void
Packit 1470ea
message_queue_source_finalize (GSource *source)
Packit 1470ea
{
Packit 1470ea
  MessageQueueSource *message_queue_source = (MessageQueueSource *) source;
Packit 1470ea
Packit 1470ea
  g_async_queue_unref (message_queue_source->queue);
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
static gboolean
Packit 1470ea
message_queue_source_closure_callback (gpointer message,
Packit 1470ea
                                       gpointer user_data)
Packit 1470ea
{
Packit 1470ea
  GClosure *closure = user_data;
Packit 1470ea
  GValue param_value = G_VALUE_INIT;
Packit 1470ea
  GValue result_value = G_VALUE_INIT;
Packit 1470ea
  gboolean retval;
Packit 1470ea
Packit 1470ea
  /* The invoked function is responsible for freeing @message. */
Packit 1470ea
  g_value_init (&result_value, G_TYPE_BOOLEAN);
Packit 1470ea
  g_value_init (&param_value, G_TYPE_POINTER);
Packit 1470ea
  g_value_set_pointer (&param_value, message);
Packit 1470ea
Packit 1470ea
  g_closure_invoke (closure, &result_value, 1, &param_value, NULL);
Packit 1470ea
  retval = g_value_get_boolean (&result_value);
Packit 1470ea
Packit 1470ea
  g_value_unset (&param_value);
Packit 1470ea
  g_value_unset (&result_value);
Packit 1470ea
Packit 1470ea
  return retval;
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
static GSourceFuncs message_queue_source_funcs =
Packit 1470ea
  {
Packit 1470ea
    message_queue_source_prepare,
Packit 1470ea
    NULL,  /* check */
Packit 1470ea
    message_queue_source_dispatch,
Packit 1470ea
    message_queue_source_finalize,
Packit 1470ea
    (GSourceFunc) message_queue_source_closure_callback,
Packit 1470ea
    NULL,
Packit 1470ea
  };
Packit 1470ea
Packit 1470ea
/**
Packit 1470ea
 * message_queue_source_new:
Packit 1470ea
 * @queue: the queue to check
Packit 1470ea
 * @destroy_message: (nullable): function to free a message, or %NULL
Packit 1470ea
 * @cancellable: (nullable): a #GCancellable, or %NULL
Packit 1470ea
 *
Packit 1470ea
 * Create a new #MessageQueueSource, a type of #GSource which dispatches for
Packit 1470ea
 * each message queued to it.
Packit 1470ea
 *
Packit 1470ea
 * If a callback function of type #MessageQueueSourceFunc is connected to the
Packit 1470ea
 * returned #GSource using g_source_set_callback(), it will be invoked for each
Packit 1470ea
 * message, with the message passed as its first argument. It is responsible for
Packit 1470ea
 * freeing the message. If no callback is set, messages are automatically freed
Packit 1470ea
 * as they are queued.
Packit 1470ea
 *
Packit 1470ea
 * Returns: (transfer full): a new #MessageQueueSource
Packit 1470ea
 */
Packit 1470ea
GSource *
Packit 1470ea
message_queue_source_new (GAsyncQueue    *queue,
Packit 1470ea
                          GDestroyNotify  destroy_message,
Packit 1470ea
                          GCancellable   *cancellable)
Packit 1470ea
{
Packit 1470ea
  GSource *source;  /* alias of @message_queue_source */
Packit 1470ea
  MessageQueueSource *message_queue_source;  /* alias of @source */
Packit 1470ea
Packit 1470ea
  g_return_val_if_fail (queue != NULL, NULL);
Packit 1470ea
  g_return_val_if_fail (cancellable == NULL ||
Packit 1470ea
                        G_IS_CANCELLABLE (cancellable), NULL);
Packit 1470ea
Packit 1470ea
  source = g_source_new (&message_queue_source_funcs,
Packit 1470ea
                         sizeof (MessageQueueSource));
Packit 1470ea
  message_queue_source = (MessageQueueSource *) source;
Packit 1470ea
Packit 1470ea
  /* The caller can overwrite this name with something more useful later. */
Packit 1470ea
  g_source_set_name (source, "MessageQueueSource");
Packit 1470ea
Packit 1470ea
  message_queue_source->queue = g_async_queue_ref (queue);
Packit 1470ea
  message_queue_source->destroy_message = destroy_message;
Packit 1470ea
Packit 1470ea
  /* Add a cancellable source. */
Packit 1470ea
  if (cancellable != NULL)
Packit 1470ea
    {
Packit 1470ea
      GSource *cancellable_source;
Packit 1470ea
Packit 1470ea
      cancellable_source = g_cancellable_source_new (cancellable);
Packit 1470ea
      g_source_set_dummy_callback (cancellable_source);
Packit 1470ea
      g_source_add_child_source (source, cancellable_source);
Packit 1470ea
      g_source_unref (cancellable_source);
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
  return source;
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
    </listing>
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="further-examples">
Packit 1470ea
    <title>Περισσότερα παραδείγματα</title>
Packit 1470ea
Packit 1470ea
    

Ο κώδικας μπορεί να είναι πιο πολύπλοκος από τα παραπάνω παραδείγματα. Στο <link href="http://nice.freedesktop.org/">libnice</link>, ένα προσαρμοσμένο GSource χρειάζεται για να λαμβάνει μια ομάδα υποδοχών που αλλάζει δυναμικά. Η υλοποίηση του γίνεται με το ComponentSource στο αρχείο <link href="http://cgit.freedesktop.org/libnice/libnice/tree/agent/component.c#n941">component.c</link> και παρουσιάζει μια πιο πολύπλοκη συνάρτηση προετοιμασίας.

Packit 1470ea
Packit 1470ea
    

Ένα άλλο παράδειγμα είναι ένας προσαρμοσμένος κώδικας για την επικοινωνία του GnuTLS με το GLib και την υλοποίηση GTlsConnection του. Το <link href="https://git.gnome.org/browse/glib-networking/tree/tls/gnutls/gtlsconnection-gnutls.c#n871">GTlsConnectionGnutlsSource</link> συγχρονίζει το κύριο νήμα με ένα νήμα TLS το οποίο εκτελεί τις εργασίες του TLS.

Packit 1470ea
  </section>
Packit 1470ea
</page>