[Spice-commits] 5 commits - configure.ac data/spicy.nsis.in gtk/continuation.c gtk/continuation.h gtk/controller gtk/coroutine.h gtk/coroutine_winfibers.c gtk/Makefile.am gtk/spice-widget.c
Marc-André Lureau
elmarco at kemper.freedesktop.org
Wed Aug 17 06:32:13 PDT 2011
configure.ac | 40 ++++++++++-----
data/spicy.nsis.in | 8 +--
gtk/Makefile.am | 14 ++++-
gtk/continuation.c | 18 +++++-
gtk/continuation.h | 2
gtk/controller/Makefile.am | 7 ++
gtk/coroutine.h | 5 +
gtk/coroutine_winfibers.c | 120 +++++++++++++++++++++++++++++++++++++++++++++
gtk/spice-widget.c | 2
9 files changed, 193 insertions(+), 23 deletions(-)
New commits:
commit f08664bdd6e53466659c8a9a473785ba2eab42b4
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Mon Aug 15 14:15:06 2011 +0200
data: fix spicy.nsis.in to include right libraries
diff --git a/data/spicy.nsis.in b/data/spicy.nsis.in
index cc9d1b4..4a01a31 100644
--- a/data/spicy.nsis.in
+++ b/data/spicy.nsis.in
@@ -77,7 +77,7 @@ Section "spicy"
File "/usr/i686-w64-mingw32/sys-root/mingw/bin/libgstvideo-0.10-0.dll"
File "/usr/i686-w64-mingw32/sys-root/mingw/bin/libgthread-2.0-0.dll"
File "/usr/i686-w64-mingw32/sys-root/mingw/bin/libgtk-win32-2.0-0.dll"
- File "/usr/i686-w64-mingw32/sys-root/mingw/bin/libiconv.dll"
+ File "/usr/i686-w64-mingw32/sys-root/mingw/bin/iconv.dll"
File "/usr/i686-w64-mingw32/sys-root/mingw/bin/libintl-8.dll"
File "/usr/i686-w64-mingw32/sys-root/mingw/bin/libjpeg-62.dll"
File "/usr/i686-w64-mingw32/sys-root/mingw/bin/liborc-0.4-0.dll"
@@ -88,7 +88,7 @@ Section "spicy"
File "/usr/i686-w64-mingw32/sys-root/mingw/bin/libpangowin32-1.0-0.dll"
File "/usr/i686-w64-mingw32/sys-root/mingw/bin/libpixman-1-0.dll"
File "/usr/i686-w64-mingw32/sys-root/mingw/bin/libpng15-15.dll"
- File "/usr/i686-w64-mingw32/sys-root/mingw/bin/libspice-client-glib-2.0-3.dll"
+ File "/usr/i686-w64-mingw32/sys-root/mingw/bin/libspice-client-glib-2.0-1.dll"
File "/usr/i686-w64-mingw32/sys-root/mingw/bin/libspice-client-gtk-2.0-1.dll"
File "/usr/i686-w64-mingw32/sys-root/mingw/bin/libssl-10.dll"
File "/usr/i686-w64-mingw32/sys-root/mingw/bin/libxml2-2.dll"
@@ -195,7 +195,7 @@ Section "Uninstall"
Delete /rebootok "$INSTDIR\bin\libxml2-2.dll"
Delete /rebootok "$INSTDIR\bin\libssl-10.dll"
Delete /rebootok "$INSTDIR\bin\libspice-client-gtk-2.0-1.dll"
- Delete /rebootok "$INSTDIR\bin\libspice-client-glib-2.0-3.dll"
+ Delete /rebootok "$INSTDIR\bin\libspice-client-glib-2.0-1.dll"
Delete /rebootok "$INSTDIR\bin\libpng15-15.dll"
Delete /rebootok "$INSTDIR\bin\libpixman-1-0.dll"
Delete /rebootok "$INSTDIR\bin\libpangowin32-1.0-0.dll"
@@ -205,7 +205,7 @@ Section "Uninstall"
Delete /rebootok "$INSTDIR\bin\liborc-0.4-0.dll"
Delete /rebootok "$INSTDIR\bin\libjpeg-62.dll"
Delete /rebootok "$INSTDIR\bin\libintl-8.dll"
- Delete /rebootok "$INSTDIR\bin\libiconv.dll"
+ Delete /rebootok "$INSTDIR\bin\iconv.dll"
Delete /rebootok "$INSTDIR\bin\libgtk-win32-2.0-0.dll"
Delete /rebootok "$INSTDIR\bin\libgthread-2.0-0.dll"
Delete /rebootok "$INSTDIR\bin\libgstvideo-0.10-0.dll"
commit 339d13d22ef7330b737d22524dd909ccc486a7ef
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Sun Aug 14 16:03:17 2011 +0200
build: fixes build with gtk3 on win32
diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index a6a0a12..208762e 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -867,7 +867,7 @@ static gboolean focus_in_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_UN
d->keyboard_have_focus = true;
try_keyboard_grab(display);
#ifdef WIN32
- focus_window = (HWND)gdk_win32_drawable_get_handle(GDK_DRAWABLE(widget->window));
+ focus_window = GDK_WINDOW_HWND(gtk_widget_get_window(widget));
g_return_val_if_fail(focus_window != NULL, true);
#endif
return true;
commit af247cb7f17fa23d962171996d4669c3c364f07e
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Sun Aug 14 16:02:45 2011 +0200
build: warn and instruct if valac is missing
diff --git a/gtk/controller/Makefile.am b/gtk/controller/Makefile.am
index bafad58..6c2a91d 100644
--- a/gtk/controller/Makefile.am
+++ b/gtk/controller/Makefile.am
@@ -57,6 +57,13 @@ test_controller_SOURCES = test.c
test_controller_LDADD = libspice-controller.la
controller.vala.stamp: $(libspice_controller_la_VALASOURCES) custom.vapi
+ @if test -z "$(VALAC)"; then \
+ echo "" ; \
+ echo " *** Error: missing valac!" ; \
+ echo " *** You must run autogen.sh or configure --enable-vala" ; \
+ echo "" ; \
+ exit 1 ; \
+ fi
$(VALA_V)$(VALAC) $(VALAFLAGS) $(AM_VALAFLAGS) $(libspice_controller_la_VALASOURCES) -H spice-controller.h
@touch $@
commit 71fdaa9b3649dc860b6c5e3896cc72d7c9cf68f8
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Fri Aug 12 17:35:39 2011 +0200
gtk: implement coroutines using Windows fibers
diff --git a/configure.ac b/configure.ac
index 8c9c5db..e60ed78 100644
--- a/configure.ac
+++ b/configure.ac
@@ -311,31 +311,49 @@ else
fi
AC_ARG_WITH([coroutine],
- AS_HELP_STRING([--with-coroutine=@<:@ucontext/gthread@:>@],
- [use ucontext or GThread for coroutines @<:@default=ucontext@:>@]),
+ AS_HELP_STRING([--with-coroutine=@<:@ucontext/gthread/winfiber/auto@:>@],
+ [use ucontext or GThread for coroutines @<:@default=auto@:>@]),
[],
- [with_coroutine=ucontext])
+ [with_coroutine=auto])
case $with_coroutine in
- ucontext|gthread) ;;
+ ucontext|gthread|winfiber|auto) ;;
*) AC_MSG_ERROR(Unsupported coroutine type)
esac
+if test "$with_coroutine" = "auto"; then
+ if test "$os_win32" = "yes"; then
+ with_coroutine=winfiber
+ else
+ with_coroutine=ucontext
+ fi
+fi
+
if test "$with_coroutine" = "ucontext"; then
AC_CHECK_FUNC(makecontext, [],[with_coroutine=gthread])
AC_CHECK_FUNC(swapcontext, [],[with_coroutine=gthread])
AC_CHECK_FUNC(getcontext, [],[with_coroutine=gthread])
fi
-if test "$with_coroutine" = "gthread"; then
- # gthread is required anyway
- WITH_UCONTEXT=0
-else
- WITH_UCONTEXT=1
-fi
+WITH_UCONTEXT=0
+WITH_GTHREAD=0
+WITH_WINFIBER=0
+
+case $with_coroutine in
+ ucontext) WITH_UCONTEXT=1 ;;
+ gthread) WITH_GTHREAD=1 ;;
+ winfiber) WITH_WINFIBER=1 ;;
+ *) AC_MSG_ERROR(Unsupported coroutine type)
+esac
AC_DEFINE_UNQUOTED(WITH_UCONTEXT,[$WITH_UCONTEXT], [Whether to use ucontext coroutine impl])
-AM_CONDITIONAL(WITH_UCONTEXT, [test "$WITH_UCONTEXT" != "0"])
+AM_CONDITIONAL(WITH_UCONTEXT, [test "x$WITH_UCONTEXT" = "x1"])
+
+AC_DEFINE_UNQUOTED(WITH_WINFIBER,[$WITH_WINFIBER], [Whether to use fiber coroutine impl])
+AM_CONDITIONAL(WITH_WINFIBER, [test "x$WITH_WINFIBER" = "x1"])
+
+AC_DEFINE_UNQUOTED(WITH_GTHREAD,[$WITH_GTHREAD], [Whether to use gthread coroutine impl])
+AM_CONDITIONAL(WITH_GTHREAD, [test "x$WITH_GTHREAD" = "x1"])
AM_CONDITIONAL([HAVE_INTROSPECTION], [test "0" != "1"])
PKG_CHECK_MODULES([GOBJECT_INTROSPECTION],
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index edec166..cbcaa79 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -10,6 +10,10 @@ EXTRA_DIST = \
keymap-gen.pl \
keymaps.csv \
decode-glz-tmpl.c \
+ coroutine_gthread.c \
+ coroutine_ucontext.c \
+ coroutine_winfibers.c \
+ continuation.h continuation.c \
map-file \
$(NULL)
@@ -255,11 +259,15 @@ endif
if WITH_UCONTEXT
libspice_client_glib_2_0_la_SOURCES += continuation.h continuation.c coroutine_ucontext.c
-EXTRA_DIST += coroutine_gthread.c
-else
+endif
+
+if WITH_WINFIBER
+libspice_client_glib_2_0_la_SOURCES += coroutine_winfibers.c
+endif
+
+if WITH_GTHREAD
libspice_client_glib_2_0_la_SOURCES += coroutine_gthread.c
libspice_client_glib_2_0_la_LIBADD += $(GTHREAD_LIBS)
-EXTRA_DIST += continuation.h continuation.c coroutine_ucontext.c
endif
displaysrc = \
diff --git a/gtk/continuation.c b/gtk/continuation.c
index 6eaed3c..9cdd578 100644
--- a/gtk/continuation.c
+++ b/gtk/continuation.c
@@ -81,9 +81,9 @@ int cc_swap(struct continuation *from, struct continuation *to)
if (getcontext(&to->last) == -1)
return -1;
else if (to->exited == 0)
- to->exited = 1;
- else if (to->exited == 1)
- return 1;
+ to->exited = 1; // so when coroutine finishes
+ else if (to->exited == 1)
+ return 1; // it ends up here
if (_setjmp(from->jmp) == 0)
_longjmp(to->jmp, 1);
diff --git a/gtk/coroutine.h b/gtk/coroutine.h
index 90ad9e8..031a97b 100644
--- a/gtk/coroutine.h
+++ b/gtk/coroutine.h
@@ -25,6 +25,8 @@
#if WITH_UCONTEXT
#include "continuation.h"
+#elif WITH_WINFIBER
+#include <windows.h>
#else
#include <glib.h>
#endif
@@ -44,6 +46,9 @@ struct coroutine
#if WITH_UCONTEXT
struct continuation cc;
+#elif WITH_WINFIBER
+ LPVOID fiber;
+ int ret;
#else
GThread *thread;
gboolean runnable;
diff --git a/gtk/coroutine_winfibers.c b/gtk/coroutine_winfibers.c
new file mode 100644
index 0000000..a22da3b
--- /dev/null
+++ b/gtk/coroutine_winfibers.c
@@ -0,0 +1,120 @@
+/*
+ * SpiceGtk coroutine with Windows fibers
+ *
+ * Copyright (C) 2011 Marc-André Lureau <marcandre.lureau at redhat.com>
+ *
+ * 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.0 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+
+#include "coroutine.h"
+
+static struct coroutine leader = { 0, };
+static struct coroutine *current = NULL;
+static struct coroutine *caller = NULL;
+
+int coroutine_release(struct coroutine *co)
+{
+ DeleteFiber(co->fiber);
+ return 0;
+}
+
+static void WINAPI coroutine_trampoline(LPVOID lpParameter)
+{
+ struct coroutine *co = (struct coroutine *)lpParameter;
+
+ co->data = co->entry(co->data);
+
+ if (co->release)
+ co->ret = co->release(co);
+ else
+ co->ret = 0;
+
+ co->caller = NULL;
+
+ // and switch back to caller
+ co->ret = 1;
+ SwitchToFiber(caller->fiber);
+}
+
+int coroutine_init(struct coroutine *co)
+{
+ if (leader.fiber == NULL) {
+ leader.fiber = ConvertThreadToFiber(&leader);
+ if (leader.fiber == NULL)
+ return -1;
+ }
+
+ co->fiber = CreateFiber(0, &coroutine_trampoline, co);
+ if (co->fiber == NULL)
+ return -1;
+
+ return 0;
+}
+
+struct coroutine *coroutine_self(void)
+{
+ if (current == NULL)
+ current = &leader;
+ return current;
+}
+
+void *coroutine_swap(struct coroutine *from, struct coroutine *to, void *arg)
+{
+ to->data = arg;
+ current = to;
+ caller = from;
+ SwitchToFiber(to->fiber);
+ if (to->ret == 0)
+ return from->data;
+ else if (to->ret == 1) {
+ coroutine_release(to);
+ current = &leader;
+ to->exited = 1;
+ return to->data;
+ }
+
+ return NULL;
+}
+
+void *coroutine_yieldto(struct coroutine *to, void *arg)
+{
+ if (to->caller) {
+ fprintf(stderr, "Co-routine is re-entering itself\n");
+ abort();
+ }
+ to->caller = coroutine_self();
+ return coroutine_swap(coroutine_self(), to, arg);
+}
+
+void *coroutine_yield(void *arg)
+{
+ struct coroutine *to = coroutine_self()->caller;
+ if (!to) {
+ fprintf(stderr, "Co-routine is yielding to no one\n");
+ abort();
+ }
+ coroutine_self()->caller = NULL;
+ return coroutine_swap(coroutine_self(), to, arg);
+}
+/*
+ * Local variables:
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
commit 1cbfe2b8fccb86a20039867fc33bc475f358f8e4
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Fri Aug 12 16:32:20 2011 +0200
use _setjmp/_longjmp to speed up coroutine switching
As described in http://www.1024cores.net/home/lock-free-algorithms/tricks/fibers
diff --git a/gtk/continuation.c b/gtk/continuation.c
index 4f5b027..6eaed3c 100644
--- a/gtk/continuation.c
+++ b/gtk/continuation.c
@@ -21,6 +21,7 @@
#include <config.h>
#include "continuation.h"
+#undef _FORTIFY_SOURCE
/*
* va_args to makecontext() must be type 'int', so passing
@@ -40,6 +41,11 @@ static void continuation_trampoline(int i0, int i1)
arg.i[1] = i1;
cc = arg.p;
+ if (_setjmp(cc->jmp) == 0) {
+ ucontext_t tmp;
+ swapcontext(&tmp, &cc->last);
+ }
+
cc->entry(cc);
}
@@ -56,6 +62,7 @@ int cc_init(struct continuation *cc)
cc->uc.uc_stack.ss_flags = 0;
makecontext(&cc->uc, (void *)continuation_trampoline, 2, arg.i[0], arg.i[1]);
+ swapcontext(&cc->last, &cc->uc);
return 0;
}
@@ -78,7 +85,10 @@ int cc_swap(struct continuation *from, struct continuation *to)
else if (to->exited == 1)
return 1;
- return swapcontext(&from->uc, &to->uc);
+ if (_setjmp(from->jmp) == 0)
+ _longjmp(to->jmp, 1);
+
+ return 0;
}
/*
* Local variables:
diff --git a/gtk/continuation.h b/gtk/continuation.h
index 87cd4ee..1247337 100644
--- a/gtk/continuation.h
+++ b/gtk/continuation.h
@@ -23,6 +23,7 @@
#include <stddef.h>
#include <ucontext.h>
+#include <setjmp.h>
struct continuation
{
@@ -35,6 +36,7 @@ struct continuation
ucontext_t uc;
ucontext_t last;
int exited;
+ jmp_buf jmp;
};
int cc_init(struct continuation *cc);
More information about the Spice-commits
mailing list