summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2013-11-19 15:29:28 +0100
committerMarc-André Lureau <marcandre.lureau@redhat.com>2013-11-20 16:32:07 +0100
commit0508f586be974a49497a15d5ce39b2f94b68a4bf (patch)
treeae0f3370f6842a0b3b3f763776bbd491f6c680fd
parentaf28d1acd6fd9f10de6f2f45210c81d9b87c6a44 (diff)
coroutine: error out on OOM or impossible conditions
Take an approach similar to gthreads, which are considered as low level/must work features by glib, which aborts on failures.
-rw-r--r--gtk/continuation.c9
-rw-r--r--gtk/continuation.h2
-rw-r--r--gtk/coroutine.h3
-rw-r--r--gtk/coroutine_gthread.c12
-rw-r--r--gtk/coroutine_ucontext.c18
-rw-r--r--gtk/coroutine_winfibers.c9
-rw-r--r--gtk/spice-channel.c9
7 files changed, 23 insertions, 39 deletions
diff --git a/gtk/continuation.c b/gtk/continuation.c
index 2891a25..d1249d6 100644
--- a/gtk/continuation.c
+++ b/gtk/continuation.c
@@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <config.h>
+#include <errno.h>
+#include <glib.h>
#undef _FORTIFY_SOURCE
@@ -49,13 +51,12 @@ static void continuation_trampoline(int i0, int i1)
cc->entry(cc);
}
-int cc_init(struct continuation *cc)
+void cc_init(struct continuation *cc)
{
volatile union cc_arg arg;
arg.p = cc;
if (getcontext(&cc->uc) == -1)
- return -1;
-
+ g_error("getcontext() failed: %s", g_strerror(errno));
cc->uc.uc_link = &cc->last;
cc->uc.uc_stack.ss_sp = cc->stack;
cc->uc.uc_stack.ss_size = cc->stack_size;
@@ -63,8 +64,6 @@ int cc_init(struct continuation *cc)
makecontext(&cc->uc, (void *)continuation_trampoline, 2, arg.i[0], arg.i[1]);
swapcontext(&cc->last, &cc->uc);
-
- return 0;
}
int cc_release(struct continuation *cc)
diff --git a/gtk/continuation.h b/gtk/continuation.h
index 1247337..675a257 100644
--- a/gtk/continuation.h
+++ b/gtk/continuation.h
@@ -39,7 +39,7 @@ struct continuation
jmp_buf jmp;
};
-int cc_init(struct continuation *cc);
+void cc_init(struct continuation *cc);
int cc_release(struct continuation *cc);
diff --git a/gtk/coroutine.h b/gtk/coroutine.h
index ef6f3db..adfc338 100644
--- a/gtk/coroutine.h
+++ b/gtk/coroutine.h
@@ -56,7 +56,8 @@ struct coroutine
};
#define IN_MAIN_CONTEXT (coroutine_self() == NULL || coroutine_is_main_context(coroutine_self()))
-int coroutine_init(struct coroutine *co) G_GNUC_WARN_UNUSED_RESULT;
+
+void coroutine_init(struct coroutine *co);
int coroutine_release(struct coroutine *co);
diff --git a/gtk/coroutine_gthread.c b/gtk/coroutine_gthread.c
index ab30631..367f325 100644
--- a/gtk/coroutine_gthread.c
+++ b/gtk/coroutine_gthread.c
@@ -86,8 +86,10 @@ static gpointer coroutine_thread(gpointer opaque)
return NULL;
}
-int coroutine_init(struct coroutine *co)
+void coroutine_init(struct coroutine *co)
{
+ GError *err = NULL;
+
if (run_cond == NULL)
coroutine_system_init();
@@ -95,15 +97,13 @@ int coroutine_init(struct coroutine *co)
co->thread = g_thread_create_full(coroutine_thread, co, co->stack_size,
FALSE, TRUE,
G_THREAD_PRIORITY_NORMAL,
- NULL);
- if (co->thread == NULL)
- return -1;
+ &err);
+ if (err != NULL)
+ g_error("g_thread_create_full() failed: %s", err->message);
co->exited = 0;
co->runnable = FALSE;
co->caller = NULL;
-
- return 0;
}
int coroutine_release(struct coroutine *co G_GNUC_UNUSED)
diff --git a/gtk/coroutine_ucontext.c b/gtk/coroutine_ucontext.c
index 4689166..6a5eb54 100644
--- a/gtk/coroutine_ucontext.c
+++ b/gtk/coroutine_ucontext.c
@@ -63,10 +63,8 @@ static void coroutine_trampoline(struct continuation *cc)
co->data = co->entry(co->data);
}
-int coroutine_init(struct coroutine *co)
+void coroutine_init(struct coroutine *co)
{
- int inited;
-
if (co->stack_size == 0)
co->stack_size = 16 << 20;
@@ -76,20 +74,14 @@ int coroutine_init(struct coroutine *co)
MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0);
if (co->cc.stack == MAP_FAILED)
- g_error("Failed to allocate %u bytes for coroutine stack: %s",
- (unsigned)co->stack_size, strerror(errno));
+ g_error("mmap(%" G_GSIZE_FORMAT ") failed: %s",
+ co->stack_size, g_strerror(errno));
+
co->cc.entry = coroutine_trampoline;
co->cc.release = _coroutine_release;
co->exited = 0;
- inited = cc_init(&co->cc);
- if (inited != 0) {
- munmap(co->cc.stack, co->cc.stack_size);
- co->cc.stack = NULL;
- co->exited = 1;
- }
-
- return inited;
+ cc_init(&co->cc);
}
#if 0
diff --git a/gtk/coroutine_winfibers.c b/gtk/coroutine_winfibers.c
index 266b1de..1ed1981 100644
--- a/gtk/coroutine_winfibers.c
+++ b/gtk/coroutine_winfibers.c
@@ -51,20 +51,19 @@ static void WINAPI coroutine_trampoline(LPVOID lpParameter)
SwitchToFiber(caller->fiber);
}
-int coroutine_init(struct coroutine *co)
+void coroutine_init(struct coroutine *co)
{
if (leader.fiber == NULL) {
leader.fiber = ConvertThreadToFiber(&leader);
if (leader.fiber == NULL)
- return -1;
+ g_error("ConvertThreadToFiber() failed");
}
co->fiber = CreateFiber(0, &coroutine_trampoline, co);
- co->ret = 0;
if (co->fiber == NULL)
- return -1;
+ g_error("CreateFiber() failed");
- return 0;
+ co->ret = 0;
}
struct coroutine *coroutine_self(void)
diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
index 2c8c1b9..a045767 100644
--- a/gtk/spice-channel.c
+++ b/gtk/spice-channel.c
@@ -2366,7 +2366,6 @@ static gboolean connect_delayed(gpointer data)
SpiceChannel *channel = data;
SpiceChannelPrivate *c = channel->priv;
struct coroutine *co;
- int inited;
CHANNEL_DEBUG(channel, "Open coroutine starting %p", channel);
c->connect_delayed_id = 0;
@@ -2377,13 +2376,7 @@ static gboolean connect_delayed(gpointer data)
co->entry = spice_channel_coroutine;
co->release = NULL;
- inited = coroutine_init(co);
- if (inited != 0) {
- g_warning("Failed to initialize channel coroutine");
- CHANNEL_DEBUG(channel, "coroutine_init failed");
- g_object_unref(G_OBJECT(channel));
- return FALSE;
- }
+ coroutine_init(co);
coroutine_yieldto(co, channel);
return FALSE;