GLib:g_source_remove()没有停止非默认GMainContext上的超时回调

时间:2017-11-30 09:20:01

标签: glib

我正在使用此函数向特定GMainContext添加超时回调(重复)。

guint GstThreadHelper::timeoutAdd(guint delay, GSourceFunc function, gpointer data) {
    // See https://developer.gnome.org/programming-guidelines/stable/main-contexts.html.en#implicit-use-of-the-global-default-main-context
    // It is important that all thread functions we invoke don't implicitly decide a maincontext.
    // We must manually provide one.
    GSource *source = NULL;
    guint id;

    source = g_timeout_source_new(delay);
    g_source_set_callback (source, function, data, NULL);
    id = g_source_attach (source, priv->mainContext);
    g_source_unref (source);

    return id;
}

稍后,我使用返回的id取消回调。

void GstThreadHelper::timeoutRemove(guint id) {
    g_source_remove(id);
}

然而,回调仍然被调用。这是我的回调。

static gboolean position_update (gpointer user_data)
{
    Player::PrivateData* priv = (Player::PrivateData*)user_data;
    gint64 pos = 0;

    if (gst_element_query_position (priv->playbin, GST_FORMAT_TIME, &pos)) {
        pos = pos / 1000000;
        priv->callback->PositionChanged(pos);
    }

    // Call me again
    return TRUE;
}

我知道我要回归TRUE,但我的理解是它仍然应该停止。如果我通过返回FALSE取消回调,我就不会打扰g_source_remove来电。

为什么g_source_remove没有阻止我的回调被提出?

修改

如果我用这个替换我的timeoutAdd方法......

guint GstThreadHelper::timeoutAdd(guint delay, GSourceFunc function, gpointer data) {
    return g_timeout_add(delay, function, data);
}

......它有效。但是,我不能使用它,因为它不会触发特定GMainContext的回调,而不是默认的全局GMainContext

EDIT2

我将g_timeout_add_seconds_full的默认来源复制到我的函数中,并且有效。

但是,当我更改g_source_attach以使用我的私人GMainContext时,它失败了。

问题与调用g_source_remove在非默认GMainContext上添加的超时有关。

1 个答案:

答案 0 :(得分:0)

事实证明g_source_remove假设您使用的是全局/默认GMainContext,在这种情况下,我不是。{/ p>

我不记得在文档中阅读过这篇文章。

无论如何,这是解决方案。

void GstThreadHelper::timeoutRemove(guint id) {
    GSource* source = g_main_context_find_source_by_id(priv->mainContext, id);
    if (source)
        g_source_destroy (source);
}

这基本上是g_source_remove正在做的事情,而是使用我们的私人GMainContext