2017-06-11 11 views
0

GTK +アプリケーション内で、GtkFileChooserWidgetのインスタンスが永続的に表示されます。ファイルを選択することにより(シングルクリック)、ユーザはファイルを処理することができる。これは、コールバック関数switch_file()によって行われます。LinuxのCのGTK + 3.0:シグナルによるコールバック関数の複数の呼び出しを処理します。

g_signal_connect (chooser, "selection-changed", G_CALLBACK (switch_file), gs); 

switch_file()関数は、モーダルダイアログでのユーザーの応答を待つため、時には遅いことがあります。 FileChooserで現在選択されているファイルが(アプリケーション自体またはシステム上の他のプロセスによって)削除されない限り、すべて正常に動作します。明らかに独自のスレッドで実行されるFileChooserはswitch_file()へのセカンダリコールを送信し、混乱を招きます。私はミューテックスを使用して複数の呼び出しを防ぐことを試みた:

static void switch_file (GtkWidget *widget, gpointer data) 
{ 
    info_t *gs = data; 
    int err; 

    if ((err = pthread_mutex_lock (&gs->mutex))) 
     DebugExit ("pthread_mutex_lock(): %s", strerror (err)); 

    /* ... */ 
} 

しかし、コールバック関数へのすべての呼び出しは、同じスタック上に同じスレッド内で行われています。したがって、pthread_mutex_lock()への2回目の呼び出しは失敗し(PTHREAD_MUTEX_ERRORCHECK_NPが使用されます)、プロセスは終了します。

switch_file()が動作している間にコールバック関数への呼び出しを延期する可能性はありますか?ユーザイベント(キー押下)の場合、すでに動作していますが、ファイルを削除することによってパラレルに発生した信号に対しては動作しません。

シグナルを延期できない場合:選択したすべてのファイルを収集し、その後(メインスレッド内で)処理するためのシグナルセーフソリューションは何ですか?

+0

switch_file()を入力すると、信号が一時的に切断されますか?出口で再接続しますか? – Chimera

+0

GTK +を複数のスレッドで実行することはできません。すべてのGTK +のものを1つのスレッドに限定する必要があります。あなたの他のスレッドを取り除く。間違った答えが「明白」になったことが私を怖がらせ始めている。 – andlabs

+0

@Chimeraシグナルの接続を解除するには、選択項目のいくつかの変更を緩める必要があります。しかし、他に解決策がない場合は、これを試してみます。 – vsnprintf

答えて

0

最高の解決策は、信号を無視することだとわかりました。次の解決策が絶対に安全かどうかはわかりませんが、それは機能します。

static int switch_ignore = false; 

static void switch_file (GtkWidget *widget, gpointer data) 
{ 
    info_t *gs = data; 

    if (switch_ignore) 
     return; 

    switch_ignore = true; 

    /* Do some work on the file system. */ 

    switch_ignore = false; 
} 
関連する問題