--- /dev/null	2009-05-07 13:29:31.492294722 -0400
+++ gfiber/gfiber.h	2009-05-13 00:07:46.000000000 -0400
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2008-2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *
+ * Author: David Zeuthen <davidz@redhat.com>
+ */
+
+#ifndef __G_FIBER_H
+#define __G_FIBER_H
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_FIBER         (g_fiber_get_type())
+#define G_FIBER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FIBER, GFiber))
+#define G_FIBER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FIBER, GFiberClass))
+#define G_FIBER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FIBER, GFiberClass))
+#define G_IS_FIBER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FIBER))
+#define G_IS_FIBER_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FIBER))
+
+typedef struct _GFiber        GFiber;
+typedef struct _GFiberClass   GFiberClass;
+typedef struct _GFiberPrivate GFiberPrivate;
+
+struct _GFiber
+{
+  /*< private >*/
+  GObject parent_instance;
+  GFiberPrivate *priv;
+};
+
+struct _GFiberClass
+{
+  /*< private >*/
+  GObjectClass parent_class;
+
+  /*< public >*/
+
+  /* Signals */
+  void (*completed) (GFiber  *fiber,
+                     gpointer result);
+
+  /*< private >*/
+  /* Padding for future expansion */
+  void (*_g_reserved0) (void);
+  void (*_g_reserved1) (void);
+  void (*_g_reserved2) (void);
+  void (*_g_reserved3) (void);
+  void (*_g_reserved4) (void);
+  void (*_g_reserved5) (void);
+  void (*_g_reserved6) (void);
+  void (*_g_reserved7) (void);
+};
+
+GType                g_fiber_get_type       (void) G_GNUC_CONST;
+
+typedef gpointer (*GFiberFunc) (GFiber       *fiber,
+                                GCancellable *cancellable,
+                                gpointer      data);
+
+/* construction and API to use outside the fiber */
+GFiber              *g_fiber_new                       (GFiberFunc     fiber_func,
+                                                        GCancellable  *cancellable,
+                                                        gpointer       data);
+void                 g_fiber_cancel                    (GFiber        *fiber);
+
+/* API to use insider the fiber */
+GAsyncReadyCallback  g_fiber_get_async_ready_callback  (GFiber        *fiber);
+gpointer             g_fiber_get_async_ready_user_data (GFiber        *fiber);
+GAsyncResult        *g_fiber_get_async_result          (GFiber        *fiber);
+void                 g_fiber_yield                     (GFiber        *fiber);
+void                 g_fiber_sleep                     (GFiber        *fiber,
+                                                        guint          msec);
+
+G_END_DECLS
+
+#endif /* __G_FIBER_H */
--- /dev/null	2009-05-07 13:29:31.492294722 -0400
+++ gfiber/main.c	2009-05-13 00:02:18.000000000 -0400
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2008-2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *
+ * Author: David Zeuthen <davidz@redhat.com>
+ */
+
+#include <string.h>
+#include "gfiber.h"
+
+static GMainLoop *loop;
+static int ret;
+
+static gpointer
+read_file_in_fiber (GFiber       *fiber,
+                    GCancellable *cancellable,
+                    gpointer      data)
+{
+  const gchar *file_name = data;
+  GFile *file;
+  GError *error;
+  GFileInputStream *file_input_stream;
+  gchar buf[1024];
+  gssize bytes_read;
+
+  g_print ("Going to read '%s'\n", file_name);
+
+  file = g_file_new_for_commandline_arg (file_name);
+
+  g_file_read_async (file,
+                     G_PRIORITY_DEFAULT,
+                     cancellable,
+                     g_fiber_get_async_ready_callback (fiber),
+                     g_fiber_get_async_ready_user_data (fiber));
+
+  g_fiber_yield (fiber);
+
+  error = NULL;
+  file_input_stream = g_file_read_finish (file,
+                                          g_fiber_get_async_result (fiber),
+                                          &error);
+  if (file_input_stream == NULL)
+    {
+      g_printerr ("Error getting file input stream for %s: %s\n",
+                  file_name,
+                  error->message);
+      goto out;
+    }
+
+  g_debug ("Got the GFileInputStream. Now sleeping 3000 msec from fiber");
+  g_fiber_sleep (fiber, 3000);
+  g_debug ("Done sleeping 3000 msec. Now reading data from stream.");
+
+  memset (buf, '\0', sizeof buf);
+  g_input_stream_read_async (G_INPUT_STREAM (file_input_stream),
+                             buf,
+                             sizeof buf,
+                             G_PRIORITY_DEFAULT,
+                             cancellable,
+                             g_fiber_get_async_ready_callback (fiber),
+                             g_fiber_get_async_ready_user_data (fiber));
+
+  g_fiber_yield (fiber);
+
+  bytes_read = g_input_stream_read_finish (G_INPUT_STREAM (file_input_stream),
+                                           g_fiber_get_async_result (fiber),
+                                           &error);
+  if (bytes_read == -1)
+    {
+      g_printerr ("Error reading from file input stream for %s: %s\n",
+                  file_name,
+                  error->message);
+
+      goto out;
+    }
+
+  g_print ("Read %" G_GSSIZE_FORMAT " bytes: '%s'\n", bytes_read, buf);
+
+  ret = 0;
+
+ out:
+  if (file != NULL)
+    g_object_unref (file);
+  if (file_input_stream != NULL)
+    g_object_unref (file_input_stream);
+
+  return GUINT_TO_POINTER (bytes_read);
+}
+
+static gboolean
+do_quit (gpointer user_data)
+{
+  g_main_loop_quit (loop);
+  return FALSE;
+}
+
+static void
+fiber_completed (GFiber   *fiber,
+                 gpointer  result,
+                 gpointer  user_data)
+{
+  g_print ("in ::completed for fiber, result = %d, exiting in 1500 ms...\n",
+           GPOINTER_TO_UINT (result));
+  g_timeout_add (1500, do_quit, NULL);
+}
+
+static gboolean
+print_mark (gpointer data)
+{
+  g_print ("in print_mark()\n");
+  return TRUE;
+}
+
+static gboolean
+do_cancel (gpointer user_data)
+{
+  GFiber *fiber = G_FIBER (user_data);
+  g_print ("cancelling\n");
+  g_fiber_cancel (fiber);
+  return FALSE;
+}
+
+int
+main (int argc, char *argv[])
+{
+  GFiber *fiber;
+  gboolean opt_cancel;
+  gchar *opt_filename;
+  GError *error;
+  GOptionContext *opt_context;
+  GOptionEntry opt_entries[] =
+    {
+      { "cancel", 'c', 0, G_OPTION_ARG_NONE, &opt_cancel, "Cancel", NULL },
+      { "file", 'f', 0, G_OPTION_ARG_FILENAME, &opt_filename, "Filename to read", NULL },
+      { NULL}
+    };
+
+  ret = 1;
+
+  g_type_init ();
+
+  opt_cancel = FALSE;
+  opt_filename = NULL;
+  opt_context = g_option_context_new ("GFiber example");
+  g_option_context_add_main_entries (opt_context, opt_entries, NULL);
+  if (!g_option_context_parse (opt_context, &argc, &argv, &error))
+    {
+      g_printerr ("Error parsing options: %s", error->message);
+      return 1;
+    }
+
+  if (opt_filename == NULL)
+    {
+      gchar *s;
+      s = g_option_context_get_help (opt_context, FALSE, NULL);
+      g_printerr ("%s\n", s);
+      g_free (s);
+      goto out;
+    }
+
+  loop = g_main_loop_new (NULL, FALSE);
+
+  g_timeout_add (500, print_mark, NULL);
+
+  fiber = g_fiber_new (read_file_in_fiber,
+                       NULL,
+                       opt_filename);
+  g_signal_connect (fiber,
+                    "completed",
+                    G_CALLBACK (fiber_completed),
+                    NULL);
+  if (opt_cancel)
+    g_timeout_add (2000, do_cancel, fiber);
+
+  g_main_loop_run (loop);
+  g_main_loop_unref (loop);
+
+ out:
+  g_option_context_free (opt_context);
+  return ret;
+}
--- /dev/null	2009-05-07 13:29:31.492294722 -0400
+++ gfiber/gfiber.c	2009-05-13 00:07:41.000000000 -0400
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2008-2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *
+ * Author: David Zeuthen <davidz@redhat.com>
+ */
+
+#include "gfiber.h"
+#include "libcoro/coro.h"
+
+struct _GFiberPrivate
+{
+  coro_context context;
+  coro_context main_context;
+
+  gchar *stack;
+  gsize  stack_size;
+
+  GFiberFunc    function;
+  gpointer      data;
+  GCancellable *cancellable;
+
+  gpointer      result;
+
+  GAsyncResult *async_result;
+
+  guint         sleep_timeout_id;
+};
+
+enum
+{
+  PROP_0,
+  PROP_FUNCTION,
+  PROP_DATA,
+  PROP_CANCELLABLE
+};
+
+enum
+{
+  COMPLETED_SIGNAL,
+  LAST_SIGNAL
+};
+
+guint signals[LAST_SIGNAL] = {0};
+
+G_DEFINE_TYPE (GFiber, g_fiber, G_TYPE_OBJECT);
+
+static void
+g_fiber_finalize (GObject *object)
+{
+  GFiber *fiber = G_FIBER (object);
+
+  g_free (fiber->priv->stack);
+  g_object_unref (fiber->priv->cancellable);
+
+  if (G_OBJECT_CLASS (g_fiber_parent_class)->finalize != NULL)
+    G_OBJECT_CLASS (g_fiber_parent_class)->finalize (object);
+}
+
+static void
+g_fiber_set_property (GObject      *object,
+                      guint         prop_id,
+                      const GValue *value,
+                      GParamSpec   *pspec)
+{
+  GFiber *fiber = G_FIBER (object);
+
+  switch (prop_id)
+    {
+    case PROP_FUNCTION:
+      fiber->priv->function = g_value_get_pointer (value);
+      break;
+
+    case PROP_DATA:
+      fiber->priv->data = g_value_get_pointer (value);
+      break;
+
+    case PROP_CANCELLABLE:
+      fiber->priv->cancellable = g_value_get_object (value);
+      if (fiber->priv->cancellable != NULL)
+        g_object_ref (fiber->priv->cancellable);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static gboolean
+terminate_fiber_in_idle (gpointer user_data)
+{
+  GFiber *fiber = G_FIBER (user_data);
+
+  /* emit the ::completed signal with the result */
+  g_signal_emit (fiber, signals[COMPLETED_SIGNAL], 0, fiber->priv->result);
+
+  /* and we're done */
+  g_object_unref (fiber);
+
+  return FALSE;
+}
+
+static void
+run_fiber_func (void *data)
+{
+  GFiber *fiber = G_FIBER (data);
+
+  /* ok, we're now in our own context, run the fiber function */
+  fiber->priv->result = fiber->priv->function (fiber,
+                                               fiber->priv->cancellable,
+                                               fiber->priv->data);
+
+  /* schedule result emission for idle */
+  g_idle_add (terminate_fiber_in_idle, fiber);
+
+  /* back to where we started.... */
+  coro_transfer (&fiber->priv->context, &fiber->priv->main_context);
+}
+
+static gboolean
+run_fiber_in_idle (gpointer user_data)
+{
+  GFiber *fiber = G_FIBER (user_data);
+
+  fiber->priv->stack = g_malloc0 (1024 * 1024);
+  fiber->priv->stack_size = 1024 * 1024;
+
+  coro_create (&fiber->priv->main_context,
+               NULL,
+               NULL,
+               NULL,
+               0);
+
+  coro_create (&fiber->priv->context,
+               run_fiber_func,
+               fiber,
+               fiber->priv->stack,
+               fiber->priv->stack_size);
+
+  coro_transfer (&fiber->priv->main_context, &fiber->priv->context);
+
+  g_object_unref (fiber);
+  return FALSE;
+}
+
+static void
+g_fiber_constructed (GObject *object)
+{
+  GFiber *fiber = G_FIBER (object);
+
+  if (fiber->priv->cancellable == NULL)
+    fiber->priv->cancellable = g_cancellable_new ();
+
+  g_idle_add (run_fiber_in_idle, g_object_ref (fiber));
+
+  if (G_OBJECT_CLASS (g_fiber_parent_class)->constructed != NULL)
+    G_OBJECT_CLASS (g_fiber_parent_class)->constructed (object);
+}
+
+static void
+g_fiber_class_init (GFiberClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->set_property = g_fiber_set_property;
+  gobject_class->constructed =  g_fiber_constructed;
+  gobject_class->finalize =     g_fiber_finalize;
+
+  g_type_class_add_private (klass, sizeof (GFiberPrivate));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_FUNCTION,
+                                   g_param_spec_pointer ("function",
+                                                         "Function",
+                                                         "The function pointer for the fiber",
+                                                         G_PARAM_WRITABLE |
+                                                         G_PARAM_CONSTRUCT_ONLY |
+                                                         G_PARAM_STATIC_NAME |
+                                                         G_PARAM_STATIC_BLURB |
+                                                         G_PARAM_STATIC_NICK));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_DATA,
+                                   g_param_spec_pointer ("data",
+                                                         "Data",
+                                                         "Data passed to fiber function",
+                                                         G_PARAM_WRITABLE |
+                                                         G_PARAM_CONSTRUCT_ONLY |
+                                                         G_PARAM_STATIC_NAME |
+                                                         G_PARAM_STATIC_BLURB |
+                                                         G_PARAM_STATIC_NICK));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_CANCELLABLE,
+                                   g_param_spec_object ("cancellable",
+                                                        "Cancellation object",
+                                                        "The cancellation object used for the fiber",
+                                                        G_TYPE_CANCELLABLE,
+                                                        G_PARAM_WRITABLE |
+                                                        G_PARAM_CONSTRUCT_ONLY |
+                                                        G_PARAM_STATIC_NAME |
+                                                        G_PARAM_STATIC_BLURB |
+                                                        G_PARAM_STATIC_NICK));
+
+  signals[COMPLETED_SIGNAL] = g_signal_new ("completed",
+                                            G_TYPE_FIBER,
+                                            G_SIGNAL_RUN_LAST,
+                                            G_STRUCT_OFFSET (GFiberClass, completed),
+                                            NULL,
+                                            NULL,
+                                            g_cclosure_marshal_VOID__POINTER,
+                                            G_TYPE_NONE,
+                                            1,
+                                            G_TYPE_POINTER);
+
+}
+
+static void
+g_fiber_init (GFiber *fiber)
+{
+  fiber->priv = G_TYPE_INSTANCE_GET_PRIVATE (fiber, G_TYPE_FIBER, GFiberPrivate);
+}
+
+
+GFiber *
+g_fiber_new (GFiberFunc     fiber_func,
+             GCancellable  *cancellable,
+             gpointer       data)
+{
+  GFiber *fiber;
+
+  fiber = G_FIBER (g_object_new (G_TYPE_FIBER,
+                                 "function", fiber_func,
+                                 "cancellable", cancellable,
+                                 "data", data,
+                                 NULL));
+
+  return fiber;
+}
+
+void
+g_fiber_cancel (GFiber *fiber)
+{
+  g_cancellable_cancel (fiber->priv->cancellable);
+  if (fiber->priv->sleep_timeout_id > 0)
+    {
+      g_source_remove (fiber->priv->sleep_timeout_id);
+      fiber->priv->sleep_timeout_id = 0;
+      coro_transfer (&fiber->priv->main_context, &fiber->priv->context);
+    }
+}
+
+static void
+generic_fiber_async_cb (GObject *source_object,
+                        GAsyncResult *res,
+                        gpointer user_data)
+{
+  GFiber *fiber = G_FIBER (user_data);
+
+  fiber->priv->async_result = res;
+
+  coro_transfer (&fiber->priv->main_context, &fiber->priv->context);
+}
+
+GAsyncReadyCallback
+g_fiber_get_async_ready_callback (GFiber *fiber)
+{
+  return generic_fiber_async_cb;
+}
+
+gpointer
+g_fiber_get_async_ready_user_data (GFiber *fiber)
+{
+  return fiber;
+}
+
+void
+g_fiber_yield (GFiber *fiber)
+{
+  coro_transfer (&fiber->priv->context, &fiber->priv->main_context);
+}
+
+GAsyncResult *
+g_fiber_get_async_result (GFiber *fiber)
+{
+  return fiber->priv->async_result;
+}
+
+static gboolean
+fiber_wakeup_func (gpointer user_data)
+{
+  GFiber *fiber = G_FIBER (user_data);
+
+  fiber->priv->sleep_timeout_id = 0;
+
+  coro_transfer (&fiber->priv->main_context, &fiber->priv->context);
+
+  return FALSE;
+}
+
+void
+g_fiber_sleep (GFiber *fiber, guint msec)
+{
+  fiber->priv->sleep_timeout_id = g_timeout_add (msec, fiber_wakeup_func, fiber);
+  g_fiber_yield (fiber);
+}
+
--- /dev/null	2009-05-07 13:29:31.492294722 -0400
+++ gfiber/libcoro/coro.h	2009-05-12 22:54:41.000000000 -0400
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2001-2008 Marc Alexander Lehmann <schmorp@schmorp.de>
+ * 
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ * 
+ *   1.  Redistributions of source code must retain the above copyright notice,
+ *       this list of conditions and the following disclaimer.
+ * 
+ *   2.  Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
+ * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
+ * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
+ * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License ("GPL") version 2 or any later version,
+ * in which case the provisions of the GPL are applicable instead of
+ * the above. If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the BSD license, indicate your decision
+ * by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL. If you do not delete the
+ * provisions above, a recipient may use your version of this file under
+ * either the BSD or the GPL.
+ *
+ * This library is modelled strictly after Ralf S. Engelschalls article at
+ * http://www.gnu.org/software/pth/rse-pmt.ps. So most of the credit must
+ * go to Ralf S. Engelschall <rse@engelschall.com>.
+ *
+ * This coroutine library is very much stripped down. You should either
+ * build your own process abstraction using it or - better - just use GNU
+ * Portable Threads, http://www.gnu.org/software/pth/.
+ *
+ */
+
+/*
+ * 2006-10-26 Include stddef.h on OS X to work around one of its bugs.
+ *            Reported by Michael_G_Schwern.
+ * 2006-11-26 Use _setjmp instead of setjmp on GNU/Linux.
+ * 2007-04-27 Set unwind frame info if gcc 3+ and ELF is detected.
+ *            Use _setjmp instead of setjmp on _XOPEN_SOURCE >= 600.
+ * 2007-05-02 Add assembly versions for x86 and amd64 (to avoid reliance
+ *            on SIGUSR2 and sigaltstack in Crossfire).
+ * 2008-01-21 Disable CFI usage on anything but GNU/Linux.
+ * 2008-03-02 Switched to 2-clause BSD license with GPL exception.
+ * 2008-04-04 New (but highly unrecommended) pthreads backend.
+ * 2008-04-24 Reinstate CORO_LOSER (had wrong stack adjustments).
+ * 2008-10-30 Support assembly method on x86 with and without frame pointer.
+ * 2008-11-03 Use a global asm statement for CORO_ASM, idea by pippijn.
+ * 2008-11-05 Hopefully fix misaligned stacks with CORO_ASM/SETJMP.
+ * 2008-11-07 rbp wasn't saved in CORO_ASM on x86_64.
+ *            introduce coro_destroy, which is a nop except for pthreads.
+ *            speed up CORO_PTHREAD. Do no longer leak threads either.
+ *            coro_create now allows one to create source coro_contexts.
+ *            do not rely on makecontext passing a void * correctly.
+ *            try harder to get _setjmp/_longjmp.
+ *            major code cleanup/restructuring.
+ * 2008-11-10 the .cfi hacks are no longer needed.
+ * 2008-11-16 work around a freebsd pthread bug.
+ * 2008-11-19 define coro_*jmp symbols for easier porting.
+ */
+
+#ifndef CORO_H
+#define CORO_H
+
+#define CORO_VERSION 2
+
+/*
+ * Changes since API version 1:
+ * replaced bogus -DCORO_LOOSE with gramatically more correct -DCORO_LOSER
+ */
+
+/*
+ * This library consists of only three files
+ * coro.h, coro.c and LICENSE (and optionally README)
+ *
+ * It implements what is known as coroutines, in a hopefully
+ * portable way. At the moment you have to define which kind
+ * of implementation flavour you want:
+ *
+ * -DCORO_UCONTEXT
+ *
+ *    This flavour uses SUSv2's get/set/swap/makecontext functions that
+ *    unfortunately only newer unices support.
+ *
+ * -DCORO_SJLJ
+ *
+ *    This flavour uses SUSv2's setjmp/longjmp and sigaltstack functions to
+ *    do it's job. Coroutine creation is much slower than UCONTEXT, but
+ *    context switching is often a bit cheaper. It should work on almost
+ *    all unices.
+ *
+ * -DCORO_LINUX
+ *
+ *    Old GNU/Linux systems (<= glibc-2.1) only work with this implementation
+ *    (it is very fast and therefore recommended over other methods, but
+ *    doesn't work with anything newer).
+ *
+ * -DCORO_LOSER
+ *
+ *    Microsoft's highly proprietary platform doesn't support sigaltstack, and
+ *    this automatically selects a suitable workaround for this platform.
+ *    (untested)
+ *
+ * -DCORO_IRIX
+ *
+ *    SGI's version of Microsoft's NT ;)
+ *
+ * -DCORO_ASM
+ *
+ *    Handcoded assembly, known to work only on a few architectures/ABI:
+ *    GCC + x86/IA32 and amd64/x86_64 + GNU/Linux and a few BSDs.
+ *
+ * -DCORO_PTHREAD
+ *
+ *    Use the pthread API. You have to provide <pthread.h> and -lpthread.
+ *    This is likely the slowest backend, and it also does not support fork(),
+ *    so avoid it at all costs.
+ *
+ * If you define neither of these symbols, coro.h will try to autodetect
+ * the model. This currently works for CORO_LOSER only. For the other
+ * alternatives you should check (e.g. using autoconf) and define the
+ * following symbols: HAVE_UCONTEXT_H / HAVE_SETJMP_H / HAVE_SIGALTSTACK.
+ */
+
+/*
+ * This is the type for the initialization function of a new coroutine.
+ */
+typedef void (*coro_func)(void *);
+
+/*
+ * A coroutine state is saved in the following structure. Treat it as an
+ * opaque type. errno and sigmask might be saved, but don't rely on it,
+ * implement your own switching primitive if you need that.
+ */
+typedef struct coro_context coro_context;
+
+/*
+ * This function creates a new coroutine. Apart from a pointer to an
+ * uninitialised coro_context, it expects a pointer to the entry function
+ * and the single pointer value that is given to it as argument.
+ *
+ * Allocating/deallocating the stack is your own responsibility.
+ *
+ * As a special case, if coro, arg, sptr and ssize are all zero,
+ * then an "empty" coro_context will be created that is suitable
+ * as an initial source for coro_transfer.
+ *
+ * This function is not reentrant, but putting a mutex around it
+ * will work.
+ */
+void coro_create (coro_context *ctx, /* an uninitialised coro_context */
+                  coro_func coro,    /* the coroutine code to be executed */
+                  void *arg,         /* a single pointer passed to the coro */
+                  void *sptr,        /* start of stack area */
+                  long ssize);       /* size of stack area */
+
+/*
+ * The following prototype defines the coroutine switching function. It is
+ * usually implemented as a macro, so watch out.
+ *
+ * This function is thread-safe and reentrant.
+ */
+#if 0
+void coro_transfer (coro_context *prev, coro_context *next);
+#endif
+
+/*
+ * The following prototype defines the coroutine destroy function. It is
+ * usually implemented as a macro, so watch out. It also serves
+ * no purpose unless you want to use the CORO_PTHREAD backend,
+ * where it is used to clean up the thread. You are responsible
+ * for freeing the stack and the context itself.
+ *
+ * This function is thread-safe and reentrant.
+ */
+#if 0
+void coro_destroy (coro_context *ctx);
+#endif
+
+/*
+ * That was it. No other user-visible functions are implemented here.
+ */
+
+/*****************************************************************************/
+
+#if !defined(CORO_LOSER) && !defined(CORO_UCONTEXT) \
+    && !defined(CORO_SJLJ) && !defined(CORO_LINUX) \
+    && !defined(CORO_IRIX) && !defined(CORO_ASM) \
+    && !defined(CORO_PTHREAD)
+# if defined(WINDOWS)
+#  define CORO_LOSER 1 /* you don't win with windoze */
+# elif defined(__linux) && (defined(__x86) || defined (__amd64))
+#  define CORO_ASM 1
+# elif defined(HAVE_UCONTEXT_H)
+#  define CORO_UCONTEXT 1
+# elif defined(HAVE_SETJMP_H) && defined(HAVE_SIGALTSTACK)
+#  define CORO_SJLJ 1
+# else
+error unknown or unsupported architecture
+# endif
+#endif
+
+/*****************************************************************************/
+
+#if CORO_UCONTEXT
+
+# include <ucontext.h>
+
+struct coro_context {
+  ucontext_t uc;
+};
+
+# define coro_transfer(p,n) swapcontext (&((p)->uc), &((n)->uc))
+# define coro_destroy(ctx) (void *)(ctx)
+
+#elif CORO_SJLJ || CORO_LOSER || CORO_LINUX || CORO_IRIX
+
+# if defined(CORO_LINUX) && !defined(_GNU_SOURCE)
+#  define _GNU_SOURCE /* for linux libc */
+# endif
+
+# if !CORO_LOSER
+#  include <unistd.h>
+# endif
+
+/* solaris is hopelessly borked, it expands _XOPEN_UNIX to nothing */
+# if __sun
+#  undef _XOPEN_UNIX
+#  define _XOPEN_UNIX 1
+# endif
+
+# include <setjmp.h>
+
+# if _XOPEN_UNIX > 0 || defined (_setjmp)
+#  define coro_jmp_buf      jmp_buf
+#  define coro_setjmp(env)  _setjmp (env)
+#  define coro_longjmp(env) _longjmp ((env), 1)
+# elif CORO_LOSER
+#  define coro_jmp_buf      jmp_buf
+#  define coro_setjmp(env)  setjmp (env)
+#  define coro_longjmp(env) longjmp ((env), 1)
+# else
+#  define coro_jmp_buf      sigjmp_buf
+#  define coro_setjmp(env)  sigsetjmp (env, 0)
+#  define coro_longjmp(env) siglongjmp ((env), 1)
+# endif
+
+struct coro_context {
+  coro_jmp_buf env;
+};
+
+# define coro_transfer(p,n) do { if (!coro_setjmp ((p)->env)) coro_longjmp ((n)->env); } while (0)
+# define coro_destroy(ctx) (void *)(ctx)
+
+#elif CORO_ASM
+
+struct coro_context {
+  void **sp; /* must be at offset 0 */
+};
+
+void __attribute__ ((__noinline__, __regparm__(2)))
+coro_transfer (coro_context *prev, coro_context *next);
+
+# define coro_destroy(ctx) (void *)(ctx)
+
+#elif CORO_PTHREAD
+
+# include <pthread.h>
+
+extern pthread_mutex_t coro_mutex;
+
+struct coro_context {
+  pthread_cond_t cv;
+  pthread_t id;
+};
+
+void coro_transfer (coro_context *prev, coro_context *next);
+void coro_destroy (coro_context *ctx);
+
+#endif
+
+#endif
+
--- /dev/null	2009-05-07 13:29:31.492294722 -0400
+++ gfiber/libcoro/coro.c	2009-05-12 22:54:32.000000000 -0400
@@ -0,0 +1,399 @@
+/*
+ * Copyright (c) 2001-2008 Marc Alexander Lehmann <schmorp@schmorp.de>
+ * 
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ * 
+ *   1.  Redistributions of source code must retain the above copyright notice,
+ *       this list of conditions and the following disclaimer.
+ * 
+ *   2.  Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
+ * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
+ * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
+ * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License ("GPL") version 2 or any later version,
+ * in which case the provisions of the GPL are applicable instead of
+ * the above. If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the BSD license, indicate your decision
+ * by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL. If you do not delete the
+ * provisions above, a recipient may use your version of this file under
+ * either the BSD or the GPL.
+ *
+ * This library is modelled strictly after Ralf S. Engelschalls article at
+ * http://www.gnu.org/software/pth/rse-pmt.ps. So most of the credit must
+ * go to Ralf S. Engelschall <rse@engelschall.com>.
+ */
+
+#include "coro.h"
+
+#include <string.h>
+
+/*****************************************************************************/
+/* ucontext/setjmp/asm backends                                              */
+/*****************************************************************************/
+#if CORO_UCONTEXT || CORO_SJLJ || CORO_LOSER || CORO_LINUX || CORO_IRIX || CORO_ASM
+
+# if CORO_UCONTEXT
+#  include <stddef.h>
+# endif
+
+# if !defined(STACK_ADJUST_PTR)
+#  if __sgi
+/* IRIX is decidedly NON-unix */
+#   define STACK_ADJUST_PTR(sp,ss) ((char *)(sp) + (ss) - 8)
+#   define STACK_ADJUST_SIZE(sp,ss) ((ss) - 8)
+#  elif (__i386__ && CORO_LINUX) || (_M_IX86 && CORO_LOSER)
+#   define STACK_ADJUST_PTR(sp,ss) ((char *)(sp) + (ss))
+#   define STACK_ADJUST_SIZE(sp,ss) (ss)
+#  elif (__amd64__ && CORO_LINUX) || ((_M_AMD64 || _M_IA64) && CORO_LOSER)
+#   define STACK_ADJUST_PTR(sp,ss) ((char *)(sp) + (ss) - 8)
+#   define STACK_ADJUST_SIZE(sp,ss) (ss)
+#  else
+#   define STACK_ADJUST_PTR(sp,ss) (sp)
+#   define STACK_ADJUST_SIZE(sp,ss) (ss)
+#  endif
+# endif
+
+# include <stdlib.h>
+
+# if CORO_SJLJ
+#  include <stdio.h>
+#  include <signal.h>
+#  include <unistd.h>
+# endif
+
+static coro_func coro_init_func;
+static void *coro_init_arg;
+static coro_context *new_coro, *create_coro;
+
+static void
+coro_init (void)
+{
+  volatile coro_func func = coro_init_func;
+  volatile void *arg = coro_init_arg;
+
+  coro_transfer (new_coro, create_coro);
+
+  func ((void *)arg);
+
+  /* the new coro returned. bad. just abort() for now */
+  abort ();
+}
+
+# if CORO_SJLJ
+
+static volatile int trampoline_done;
+
+/* trampoline signal handler */
+static void
+trampoline (int sig)
+{
+  if (coro_setjmp (new_coro->env))
+    coro_init (); /* start it */
+  else
+    trampoline_done = 1;
+}
+
+# endif
+
+# if CORO_ASM
+
+  asm (
+       ".text\n"
+       ".globl coro_transfer\n"
+       ".type coro_transfer, @function\n"
+       "coro_transfer:\n"
+       #if __amd64
+         #define NUM_SAVED 6
+         "\tpush %rbp\n"
+         "\tpush %rbx\n"
+         "\tpush %r12\n"
+         "\tpush %r13\n"
+         "\tpush %r14\n"
+         "\tpush %r15\n"
+         "\tmov  %rsp, (%rdi)\n"
+         "\tmov  (%rsi), %rsp\n"
+         "\tpop  %r15\n"
+         "\tpop  %r14\n"
+         "\tpop  %r13\n"
+         "\tpop  %r12\n"
+         "\tpop  %rbx\n"
+         "\tpop  %rbp\n"
+       #elif __i386
+         #define NUM_SAVED 4
+         "\tpush %ebp\n"
+         "\tpush %ebx\n"
+         "\tpush %esi\n"
+         "\tpush %edi\n"
+         "\tmov  %esp, (%eax)\n"
+         "\tmov  (%edx), %esp\n"
+         "\tpop  %edi\n"
+         "\tpop  %esi\n"
+         "\tpop  %ebx\n"
+         "\tpop  %ebp\n"
+       #else
+         #error unsupported architecture
+       #endif
+       "\tret\n"
+  );
+
+# endif
+
+void
+coro_create (coro_context *ctx, coro_func coro, void *arg, void *sptr, long ssize)
+{
+  coro_context nctx;
+# if CORO_SJLJ
+  stack_t ostk, nstk;
+  struct sigaction osa, nsa;
+  sigset_t nsig, osig;
+# endif
+
+  if (!coro)
+    return;
+
+  coro_init_func = coro;
+  coro_init_arg  = arg;
+
+  new_coro    = ctx;
+  create_coro = &nctx;
+
+# if CORO_SJLJ
+  /* we use SIGUSR2. first block it, then fiddle with it. */
+
+  sigemptyset (&nsig);
+  sigaddset (&nsig, SIGUSR2);
+  sigprocmask (SIG_BLOCK, &nsig, &osig);
+
+  nsa.sa_handler = trampoline;
+  sigemptyset (&nsa.sa_mask);
+  nsa.sa_flags = SA_ONSTACK;
+
+  if (sigaction (SIGUSR2, &nsa, &osa))
+    {
+      perror ("sigaction");
+      abort ();
+    }
+
+  /* set the new stack */
+  nstk.ss_sp    = STACK_ADJUST_PTR (sptr,ssize); /* yes, some platforms (IRIX) get this wrong. */
+  nstk.ss_size  = STACK_ADJUST_SIZE (sptr,ssize);
+  nstk.ss_flags = 0;
+
+  if (sigaltstack (&nstk, &ostk) < 0)
+    {
+      perror ("sigaltstack");
+      abort ();
+    }
+
+  trampoline_done = 0;
+  kill (getpid (), SIGUSR2);
+  sigfillset (&nsig); sigdelset (&nsig, SIGUSR2);
+
+  while (!trampoline_done)
+    sigsuspend (&nsig);
+
+  sigaltstack (0, &nstk);
+  nstk.ss_flags = SS_DISABLE;
+  if (sigaltstack (&nstk, 0) < 0)
+    perror ("sigaltstack");
+
+  sigaltstack (0, &nstk);
+  if (~nstk.ss_flags & SS_DISABLE)
+    abort ();
+
+  if (~ostk.ss_flags & SS_DISABLE)
+    sigaltstack (&ostk, 0);
+
+  sigaction (SIGUSR2, &osa, 0);
+  sigprocmask (SIG_SETMASK, &osig, 0);
+
+# elif CORO_LOSER
+
+  coro_setjmp (ctx->env);
+  #if __CYGWIN__
+    ctx->env[7] = (long)((char *)sptr + ssize) - sizeof (long);
+    ctx->env[8] = (long)coro_init;
+  #elif defined(_M_IX86)
+    ((_JUMP_BUFFER *)&ctx->env)->Eip   = (long)coro_init;
+    ((_JUMP_BUFFER *)&ctx->env)->Esp   = (long)STACK_ADJUST_PTR (sptr, ssize) - sizeof (long);
+  #elif defined(_M_AMD64)
+    ((_JUMP_BUFFER *)&ctx->env)->Rip   = (__int64)coro_init;
+    ((_JUMP_BUFFER *)&ctx->env)->Rsp   = (__int64)STACK_ADJUST_PTR (sptr, ssize) - sizeof (long);
+  #elif defined(_M_IA64)
+    ((_JUMP_BUFFER *)&ctx->env)->StIIP = (__int64)coro_init;
+    ((_JUMP_BUFFER *)&ctx->env)->IntSp = (__int64)STACK_ADJUST_PTR (sptr, ssize) - sizeof (long);
+  #else
+    #error "microsoft libc or architecture not supported"
+  #endif
+
+# elif CORO_LINUX
+
+  coro_setjmp (ctx->env);
+  #if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 0 && defined (JB_PC) && defined (JB_SP)
+    ctx->env[0].__jmpbuf[JB_PC] = (long)coro_init;
+    ctx->env[0].__jmpbuf[JB_SP] = (long)STACK_ADJUST_PTR (sptr, ssize) - sizeof (long);
+  #elif __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 0 && defined (__mc68000__)
+    ctx->env[0].__jmpbuf[0].__aregs[0] = (long int)coro_init;
+    ctx->env[0].__jmpbuf[0].__sp = (int *)((char *)sptr + ssize) - sizeof (long);
+  #elif defined (__GNU_LIBRARY__) && defined (__i386__)
+    ctx->env[0].__jmpbuf[0].__pc = (char *)coro_init;
+    ctx->env[0].__jmpbuf[0].__sp = (void *)((char *)sptr + ssize) - sizeof (long);
+  #elif defined (__GNU_LIBRARY__) && defined (__amd64__)
+    ctx->env[0].__jmpbuf[JB_PC]  = (long)coro_init;
+    ctx->env[0].__jmpbuf[0].__sp = (void *)((char *)sptr + ssize) - sizeof (long);
+  #else
+    #error "linux libc or architecture not supported"
+  #endif
+
+# elif CORO_IRIX
+
+  coro_setjmp (ctx->env, 0);
+  ctx->env[JB_PC] = (__uint64_t)coro_init;
+  ctx->env[JB_SP] = (__uint64_t)STACK_ADJUST_PTR (sptr, ssize) - sizeof (long);
+
+# elif CORO_ASM
+
+  ctx->sp = (void **)(ssize + (char *)sptr);
+  *--ctx->sp = (void *)abort; /* needed for alignment only */
+  *--ctx->sp = (void *)coro_init;
+  ctx->sp -= NUM_SAVED;
+
+# elif CORO_UCONTEXT
+
+  getcontext (&(ctx->uc));
+
+  ctx->uc.uc_link           =  0;
+  ctx->uc.uc_stack.ss_sp    = sptr;
+  ctx->uc.uc_stack.ss_size  = (size_t)ssize;
+  ctx->uc.uc_stack.ss_flags = 0;
+
+  makecontext (&(ctx->uc), (void (*)())coro_init, 0);
+
+# endif
+
+  coro_transfer (create_coro, new_coro);
+}
+
+/*****************************************************************************/
+/* pthread backend                                                           */
+/*****************************************************************************/
+#elif CORO_PTHREAD
+
+/* this mutex will be locked by the running coroutine */
+pthread_mutex_t coro_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+struct coro_init_args
+{
+  coro_func func;
+  void *arg;
+  coro_context *self, *main;
+};
+
+static pthread_t null_tid;
+
+/* I'd so love to cast pthread_mutex_unlock to void (*)(void *)... */
+static void
+mutex_unlock_wrapper (void *arg)
+{
+  pthread_mutex_unlock ((pthread_mutex_t *)arg);
+}
+
+static void *
+coro_init (void *args_)
+{
+  struct coro_init_args *args = (struct coro_init_args *)args_;
+  coro_func func = args->func;
+  void *arg = args->arg;
+
+  pthread_mutex_lock (&coro_mutex);
+
+  /* we try to be good citizens and use deferred cancellation and cleanup handlers */
+  pthread_cleanup_push (mutex_unlock_wrapper, &coro_mutex);
+    coro_transfer (args->self, args->main);
+    func (arg);
+  pthread_cleanup_pop (1);
+
+  return 0;
+}
+
+void
+coro_transfer (coro_context *prev, coro_context *next)
+{
+  pthread_cond_signal (&next->cv);
+  pthread_cond_wait (&prev->cv, &coro_mutex);
+#if __FreeBSD__ /* freebsd is of course broken and needs manual testcancel calls... yay... */
+  pthread_testcancel ();
+#endif
+}
+
+void
+coro_create (coro_context *ctx, coro_func coro, void *arg, void *sptr, long ssize)
+{
+  static coro_context nctx;
+  static int once;
+
+  if (!once)
+    {
+      once = 1;
+
+      pthread_mutex_lock (&coro_mutex);
+      pthread_cond_init (&nctx.cv, 0);
+      null_tid = pthread_self ();
+    }
+
+  pthread_cond_init (&ctx->cv, 0);
+
+  if (coro)
+    {
+      pthread_attr_t attr;
+      struct coro_init_args args;
+
+      args.func = coro;
+      args.arg  = arg;
+      args.self = ctx;
+      args.main = &nctx;
+
+      pthread_attr_init (&attr);
+      pthread_attr_setstack (&attr, sptr, (size_t)ssize);
+      pthread_attr_setscope (&attr, PTHREAD_SCOPE_PROCESS);
+      pthread_create (&ctx->id, &attr, coro_init, &args);
+
+      coro_transfer (args.main, args.self);
+    }
+  else
+    ctx->id = null_tid;
+}
+
+void
+coro_destroy (coro_context *ctx)
+{
+  if (!pthread_equal (ctx->id, null_tid))
+    {
+      pthread_cancel (ctx->id);
+      pthread_mutex_unlock (&coro_mutex);
+      pthread_join (ctx->id, 0);
+      pthread_mutex_lock (&coro_mutex);
+    }
+
+  pthread_cond_destroy (&ctx->cv);
+}
+
+#else
+# error unsupported backend
+#endif
+
--- /dev/null	2009-05-07 13:29:31.492294722 -0400
+++ gfiber/libcoro/LICENSE	2009-05-12 22:54:01.000000000 -0400
@@ -0,0 +1,26 @@
+Copyright (c) 2000-2005 Marc Alexander Lehmann <schmorp@schmorp.de>
+
+Redistribution and use in source and binary forms, with or without modifica-
+tion, are permitted provided that the following conditions are met:
+
+  1.  Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+  2.  Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+  3.  The name of the author may not be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
+CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
+CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
+ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+
--- /dev/null	2009-05-07 13:29:31.492294722 -0400
+++ gfiber/libcoro/README	2009-05-12 22:54:12.000000000 -0400
@@ -0,0 +1,6 @@
+Configuration, documentation etc. is provided in the coro.h file.  Please
+note that the file conftest.c in this distribution is under the GPL. It is
+not needed for proper operation of this library though, for that, coro.h
+and coro.c suffice.
+
+Marc Lehmann <schmorp@schmorp.de>
--- /dev/null	2009-05-07 13:29:31.492294722 -0400
+++ gfiber/Makefile	2009-05-13 00:18:35.000000000 -0400
@@ -0,0 +1,20 @@
+
+NULL =
+
+gfiber : main.c gfiber.h gfiber.c libcoro/coro.h libcoro/coro.c Makefile
+	gcc -g -o gfiber \
+	main.c \
+	gfiber.h \
+	gfiber.c \
+	libcoro/coro.h \
+	libcoro/coro.c \
+	`pkg-config --cflags --libs glib-2.0 gobject-2.0 gio-2.0` \
+	$(NULL)
+
+# For using pthread simulation
+#
+#	-DCORO_PTHREAD -lpthread \
+
+clean :
+	rm -f gfiber *.o *~
+
--- /dev/null	2009-05-07 13:29:31.492294722 -0400
+++ gfiber/genpatch.sh	2009-05-13 00:18:08.000000000 -0400
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+TODAY=`date +%Y%m%d`
+PATCH=gfiber-$TODAY.patch
+FILES="gfiber.h main.c gfiber.c libcoro/coro.h libcoro/coro.c libcoro/LICENSE libcoro/README Makefile genpatch.sh"
+
+rm -f $PATCH
+cd ..
+for i in $FILES; do
+    diff -u /dev/null gfiber/$i >> gfiber/$PATCH
+done
