この関数を使用して、特定のGMainContext
にタイムアウトコールバック(繰り返し)を追加しています。GLib:g_source_remove()デフォルト以外の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
は私のコールバックが発生しないようにしますか?
EDIT私はこれで私の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
を使用するように変更した瞬間、それは失敗しました。
問題は、デフォルト以外のGMainContext
で追加されたタイムアウトについてg_source_remove
を呼び出すことと関係がある。
あなたはそれを持っています。これは 'g_source_remove()'のドキュメントで言及されています: "与えられたIDを持つソースをデフォルトのメインコンテキストから削除します"しかし、これを明確にするためにGLibに変更をプッシュします。 'g_source_destroy()'を使って(そして、 'guint'タグを渡すのではなく、' GSource * 'ポインタをあちこちに渡し、参照を保持して)、正しいです。 –