[glib/gwakeup: 4/6] GCancellable: port to GWakeup
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/gwakeup: 4/6] GCancellable: port to GWakeup
- Date: Mon, 25 Jul 2011 13:50:54 +0000 (UTC)
commit 0a971e46bf4158b7f58ac283db40d212b6f2d274
Author: Ryan Lortie <desrt desrt ca>
Date: Mon Jul 25 15:02:28 2011 +0200
GCancellable: port to GWakeup
gio/gcancellable.c | 235 +++++++---------------------------------------------
1 files changed, 32 insertions(+), 203 deletions(-)
---
diff --git a/gio/gcancellable.c b/gio/gcancellable.c
index 2974663..30bb0e9 100644
--- a/gio/gcancellable.c
+++ b/gio/gcancellable.c
@@ -22,18 +22,7 @@
#include "config.h"
#include "glib.h"
-#ifdef G_OS_UNIX
-#include "glib-unix.h"
-#ifdef HAVE_EVENTFD
-#include <sys/eventfd.h>
-#endif
-#endif
#include <gioerror.h>
-#ifdef G_OS_WIN32
-#include <errno.h>
-#include <windows.h>
-#include <io.h>
-#endif
#include "gcancellable.h"
#include "glibintl.h"
@@ -60,12 +49,7 @@ struct _GCancellablePrivate
guint cancelled_running_waiting : 1;
guint fd_refcount;
- /* If cancel_pipe[0] is != -1 and cancel_pipe[1] is -1, it is an eventfd */
- int cancel_pipe[2];
-
-#ifdef G_OS_WIN32
- HANDLE event;
-#endif
+ GWakeup *wakeup;
};
static guint signals[LAST_SIGNAL] = { 0 };
@@ -75,41 +59,14 @@ G_DEFINE_TYPE (GCancellable, g_cancellable, G_TYPE_OBJECT);
static GStaticPrivate current_cancellable = G_STATIC_PRIVATE_INIT;
G_LOCK_DEFINE_STATIC(cancellable);
static GCond *cancellable_cond = NULL;
-
-static void
-g_cancellable_close_pipe (GCancellable *cancellable)
-{
- GCancellablePrivate *priv;
-
- priv = cancellable->priv;
-
- if (priv->cancel_pipe[0] != -1)
- {
- close (priv->cancel_pipe[0]);
- priv->cancel_pipe[0] = -1;
- }
-
- if (priv->cancel_pipe[1] != -1)
- {
- close (priv->cancel_pipe[1]);
- priv->cancel_pipe[1] = -1;
- }
-
-#ifdef G_OS_WIN32
- if (priv->event)
- {
- CloseHandle (priv->event);
- priv->event = NULL;
- }
-#endif
-}
static void
g_cancellable_finalize (GObject *object)
{
GCancellable *cancellable = G_CANCELLABLE (object);
- g_cancellable_close_pipe (cancellable);
+ if (cancellable->priv->wakeup)
+ g_wakeup_free (cancellable->priv->wakeup);
G_OBJECT_CLASS (g_cancellable_parent_class)->finalize (object);
}
@@ -196,87 +153,11 @@ g_cancellable_class_init (GCancellableClass *klass)
}
static void
-g_cancellable_write_cancelled (GCancellable *cancellable)
-{
- gssize c;
- GCancellablePrivate *priv;
- const char ch = 'x';
-
- priv = cancellable->priv;
-
-#ifdef G_OS_WIN32
- if (priv->event)
- SetEvent (priv->event);
-#else
-
- if (priv->cancel_pipe[0] == -1)
- return;
-
- g_assert (cancellable->priv->cancelled);
-
-#ifdef HAVE_EVENTFD
- if (priv->cancel_pipe[1] == -1)
- {
- guint64 buf = 1;
-
- do
- c = write (priv->cancel_pipe[0], &buf, sizeof (buf));
- while (c == -1 && errno == EINTR);
-
- return;
- }
-#endif /* HAVE_EVENTFD */
-
- do
- c = write (priv->cancel_pipe[1], &ch, 1);
- while (c == -1 && errno == EINTR);
-#endif /* G_OS_WIN32 */
-}
-
-#ifndef G_OS_WIN32
-
-static void
-g_cancellable_open_pipe (GCancellable *cancellable)
-{
- GCancellablePrivate *priv;
-
- priv = cancellable->priv;
-#ifdef HAVE_EVENTFD
- priv->cancel_pipe[0] = eventfd (0, EFD_CLOEXEC | EFD_NONBLOCK);
- if (priv->cancel_pipe[0] >= 0)
- {
- if (priv->cancelled)
- g_cancellable_write_cancelled (cancellable);
- return;
- }
- else if (!(errno == ENOSYS || errno == EINVAL))
- {
- return;
- }
- /* Fall through on ENOSYS or EINVAL */
-#endif
- if (g_unix_open_pipe (priv->cancel_pipe, FD_CLOEXEC, NULL))
- {
- /* Make them nonblocking, just to be sure we don't block
- * on errors and stuff
- */
- g_unix_set_fd_nonblocking (priv->cancel_pipe[0], TRUE, NULL);
- g_unix_set_fd_nonblocking (priv->cancel_pipe[1], TRUE, NULL);
-
- if (priv->cancelled)
- g_cancellable_write_cancelled (cancellable);
- }
-}
-#endif
-
-static void
g_cancellable_init (GCancellable *cancellable)
{
cancellable->priv = G_TYPE_INSTANCE_GET_PRIVATE (cancellable,
G_TYPE_CANCELLABLE,
GCancellablePrivate);
- cancellable->priv->cancel_pipe[0] = -1;
- cancellable->priv->cancel_pipe[1] = -1;
}
/**
@@ -388,37 +269,11 @@ g_cancellable_reset (GCancellable *cancellable)
g_cond_wait (cancellable_cond,
g_static_mutex_get_mutex (& G_LOCK_NAME (cancellable)));
}
-
+
if (priv->cancelled)
{
- /* Make sure we're not leaving old cancel state around */
-
-#ifdef G_OS_WIN32
- if (priv->event)
- ResetEvent (priv->event);
-#endif
- if (priv->cancel_pipe[0] != -1)
- {
- gssize c;
-#ifdef HAVE_EVENTFD
- if (priv->cancel_pipe[1] == -1)
- {
- guint64 buf;
-
- do
- c = read (priv->cancel_pipe[0], &buf, sizeof(buf));
- while (c == -1 && errno == EINTR);
- }
- else
-#endif
- {
- char ch;
-
- do
- c = read (priv->cancel_pipe[0], &ch, 1);
- while (c == -1 && errno == EINTR);
- }
- }
+ if (priv->wakeup)
+ g_wakeup_acknowledge (priv->wakeup);
priv->cancelled = FALSE;
}
@@ -490,27 +345,15 @@ g_cancellable_set_error_if_cancelled (GCancellable *cancellable,
int
g_cancellable_get_fd (GCancellable *cancellable)
{
- GCancellablePrivate *priv;
- int fd;
-
- if (cancellable == NULL)
- return -1;
-
- priv = cancellable->priv;
+ GPollFD pollfd;
#ifdef G_OS_WIN32
- return -1;
+ pollfd.fd = -1;
#else
- G_LOCK(cancellable);
- if (priv->cancel_pipe[0] == -1)
- g_cancellable_open_pipe (cancellable);
- fd = priv->cancel_pipe[0];
- if (fd != -1)
- priv->fd_refcount++;
- G_UNLOCK(cancellable);
+ g_cancellable_make_pollfd (cancellable, &pollfd);
#endif
- return fd;
+ return pollfd.fd;
}
/**
@@ -550,39 +393,21 @@ g_cancellable_make_pollfd (GCancellable *cancellable, GPollFD *pollfd)
return FALSE;
g_return_val_if_fail (G_IS_CANCELLABLE (cancellable), FALSE);
- {
-#ifdef G_OS_WIN32
- GCancellablePrivate *priv;
-
- priv = cancellable->priv;
- G_LOCK(cancellable);
- if (priv->event == NULL)
- {
- /* A manual reset anonymous event, starting unset */
- priv->event = CreateEvent (NULL, TRUE, FALSE, NULL);
- if (priv->event == NULL)
- {
- G_UNLOCK(cancellable);
- return FALSE;
- }
- if (priv->cancelled)
- SetEvent(priv->event);
- }
- priv->fd_refcount++;
- G_UNLOCK(cancellable);
-
- pollfd->fd = (gintptr)priv->event;
-#else /* !G_OS_WIN32 */
- int fd = g_cancellable_get_fd (cancellable);
-
- if (fd == -1)
- return FALSE;
- pollfd->fd = fd;
-#endif /* G_OS_WIN32 */
- }
-
- pollfd->events = G_IO_IN;
- pollfd->revents = 0;
+ G_LOCK(cancellable);
+
+ cancellable->priv->fd_refcount++;
+
+ if (cancellable->priv->wakeup == NULL)
+ {
+ cancellable->priv->wakeup = g_wakeup_new ();
+
+ if (cancellable->priv->cancelled)
+ g_wakeup_signal (cancellable->priv->wakeup);
+ }
+
+ g_wakeup_get_pollfd (cancellable->priv->wakeup, pollfd);
+
+ G_UNLOCK(cancellable);
return TRUE;
}
@@ -619,7 +444,10 @@ g_cancellable_release_fd (GCancellable *cancellable)
G_LOCK (cancellable);
priv->fd_refcount--;
if (priv->fd_refcount == 0)
- g_cancellable_close_pipe (cancellable);
+ {
+ g_wakeup_free (priv->wakeup);
+ priv->wakeup = NULL;
+ }
G_UNLOCK (cancellable);
}
@@ -662,8 +490,9 @@ g_cancellable_cancel (GCancellable *cancellable)
priv->cancelled = TRUE;
priv->cancelled_running = TRUE;
-
- g_cancellable_write_cancelled (cancellable);
+
+ if (priv->wakeup)
+ g_wakeup_signal (priv->wakeup);
G_UNLOCK(cancellable);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]