[glib/gwakeup: 1/6] Add GWakeup



commit 78545a641cb93811640e95792eb7f87f810e7aea
Author: Ryan Lortie <desrt desrt ca>
Date:   Mon Jul 25 15:05:03 2011 +0200

    Add GWakeup
    
    GWakeup is a utility class to handle the cross-thread signalling needs
    of GMainContext and GCancellable.  It may find some other users as well.
    
    The desire here is to properly hide the implementation details in a
    module which can be properly unit tested and used in GMainContext and
    GCancellable without a rats nest of #ifdef.

 glib/Makefile.am  |    2 +
 glib/glib.h       |    1 +
 glib/glib.symbols |    5 ++
 glib/gwakeup.c    |  157 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 glib/gwakeup.h    |   38 +++++++++++++
 5 files changed, 203 insertions(+), 0 deletions(-)
---
diff --git a/glib/Makefile.am b/glib/Makefile.am
index 22680b8..b4eaefe 100644
--- a/glib/Makefile.am
+++ b/glib/Makefile.am
@@ -198,6 +198,7 @@ libglib_2_0_la_SOURCES = 	\
 	gvarianttypeinfo.h	\
 	gvarianttypeinfo.c	\
 	gvarianttype.c		\
+	gwakeup.c		\
 	gdebug.h		\
 	gprintf.c		\
 	gprintfint.h
@@ -286,6 +287,7 @@ glibsubinclude_HEADERS =   \
 	gutils.h	\
 	gvarianttype.h	\
 	gvariant.h	\
+	gwakeup.h	\
 	gwin32.h	\
 	gprintf.h
 
diff --git a/glib/glib.h b/glib/glib.h
index 06d0190..d2ce71d 100644
--- a/glib/glib.h
+++ b/glib/glib.h
@@ -90,6 +90,7 @@
 #include <glib/gutils.h>
 #include <glib/gvarianttype.h>
 #include <glib/gvariant.h>
+#include <glib/gwakeup.h>
 #ifdef G_PLATFORM_WIN32
 #include <glib/gwin32.h>
 #endif
diff --git a/glib/glib.symbols b/glib/glib.symbols
index ba24a19..18ba34d 100644
--- a/glib/glib.symbols
+++ b/glib/glib.symbols
@@ -1581,3 +1581,8 @@ glib_micro_version
 glib_minor_version
 glib_on_error_halt
 g_mem_gc_friendly
+g_wakeup_new
+g_wakeup_free
+g_wakeup_signal
+g_wakeup_acknowledge
+g_wakeup_get_pollfd
diff --git a/glib/gwakeup.c b/glib/gwakeup.c
new file mode 100644
index 0000000..60c2a9e
--- /dev/null
+++ b/glib/gwakeup.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright  2011 Canonical Limited
+ *
+ * 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 licence, 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: Ryan Lortie <desrt desrt ca>
+ */
+
+#include "config.h"
+
+#include "gwakeup.h"
+
+#ifdef _WIN32
+
+#include <windows.h>
+#include "gmessages.h"
+#include "giochannel.h"
+#include "gwin32.h"
+
+GWakeup *
+g_wakeup_new (void)
+{
+  HANDLE wakeup;
+
+  wakeup = CreateEvent (NULL, TRUE, FALSE, NULL);
+
+  if (wakeup == NULL)
+    g_error ("Cannot create event for GWakeup: %s",
+             g_win32_error_message (GetLastError ()));
+
+  return (GWakeup *) wakeup;
+}
+
+void
+g_wakeup_get_pollfd (GWakeup *wakeup,
+                     GPollFD *fd)
+{
+  fd->fd = (gintptr) wakeup;
+  fd->events = G_IO_IN;
+}
+
+void
+g_wakeup_acknowledge (GWakeup *wakeup)
+{
+  ResetEvent ((HANDLE) wakeup);
+}
+
+void
+g_wakeup_signal (GWakeup *wakeup)
+{
+  SetEvent ((HANDLE) wakeup);
+}
+
+void
+g_wakeup_free (GWakeup *wakeup)
+{
+  CloseHandle ((HANDLE) wakeup);
+}
+
+#else
+
+#include "glib-unix.h"
+#include <fcntl.h>
+
+#if defined (HAVE_EVENTFD)
+#include <sys/eventfd.h>
+#endif
+
+struct _GWakeup
+{
+  gint fds[2];
+};
+
+GWakeup *
+g_wakeup_new (void)
+{
+  GError *error = NULL;
+  GWakeup *wakeup;
+
+  wakeup = g_slice_new (GWakeup);
+
+  /* try eventfd first, if we think we can */
+#if defined (HAVE_EVENTFD)
+  wakeup->fds[0] = eventfd (0, EFD_CLOEXEC | EFD_NONBLOCK);
+
+  if (wakeup->fds[0] != -1)
+    {
+      wakeup->fds[1] = -1;
+      return wakeup;
+    }
+
+  /* for any failure, try a pipe instead */
+#endif
+
+  if (!g_unix_open_pipe (wakeup->fds, FD_CLOEXEC, &error))
+    g_error ("Creating pipes for GWakeup: %s\n", error->message);
+
+  if (!g_unix_set_fd_nonblocking (wakeup->fds[0], TRUE, &error) ||
+      !g_unix_set_fd_nonblocking (wakeup->fds[1], TRUE, &error))
+    g_error ("Set pipes non-blocking for GWakeup: %s\n", error->message);
+
+  return wakeup;
+}
+
+void
+g_wakeup_get_pollfd (GWakeup *wakeup,
+                     GPollFD *fd)
+{
+  fd->fd = wakeup->fds[0];
+  fd->events = G_IO_IN;
+}
+
+void
+g_wakeup_acknowledge (GWakeup *wakeup)
+{
+  char buffer[16];
+
+  /* read until it is empty */
+  while (read (wakeup->fds[0], buffer, sizeof buffer) == sizeof buffer);
+}
+
+void
+g_wakeup_signal (GWakeup *wakeup)
+{
+  guint64 one = 1;
+
+  if (wakeup->fds[1] == -1)
+    write (wakeup->fds[0], &one, sizeof one);
+  else
+    write (wakeup->fds[1], &one, 1);
+}
+
+void
+g_wakeup_free (GWakeup *wakeup)
+{
+  close (wakeup->fds[0]);
+
+  if (wakeup->fds[1] != -1)
+    close (wakeup->fds[1]);
+
+  g_slice_free (GWakeup, wakeup);
+}
+
+#endif /* !_WIN32 */
diff --git a/glib/gwakeup.h b/glib/gwakeup.h
new file mode 100644
index 0000000..58d592f
--- /dev/null
+++ b/glib/gwakeup.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright  2011 Canonical Limited
+ *
+ * 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 licence, 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: Ryan Lortie <desrt desrt ca>
+ */
+
+#ifndef __G_WAKEUP_H__
+#define __G_WAKEUP_H__
+
+#include <glib/gtypes.h>
+#include <glib/gpoll.h>
+
+typedef struct _GWakeup GWakeup;
+
+GWakeup *       g_wakeup_new            (void);
+void            g_wakeup_free           (GWakeup *wakeup);
+
+void            g_wakeup_get_pollfd     (GWakeup *wakeup,
+                                         GPollFD *fd);
+void            g_wakeup_signal         (GWakeup *wakeup);
+void            g_wakeup_acknowledge    (GWakeup *wakeup);
+
+#endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]