Comment dégeler mes relations avec Gtk3 ?
Bonjour,
Je suis en train de porter une application C++ de Gtk2 à Gtk3 (gtkmm donc), et je suis confronté au même type de problème, mais je pense pouvoir recréer un fonctionnement à la thread_enter/thread_leave, mais pour ça, je dois passer par gdk_threads_add_idle. Le problème, c'est que mon application ne démarre plus, elle gèle avant même d'ouvrir la première fenêtre! J'avais testé d'autres solutions qui permettais au moins d'ouvrir la fenêtre principale, avec tout ses widgets, mais cela gelais également, et parfois plantait. En fait, je ne suis pas sûr que le gèle vienne de là, car on utilise aussi gdk_threads_add_idle ici et là dans le code, mais s'il y a un problème avec cette fonction (un bug dans Glib ?), j'appliquerais les solutions partout où il le faudra.
bertrand125, pourrais-tu élaborer ton dernier commentaire? Comment savoir d'ailleurs s'il faut utiliser gtk_main_iteration() ou gtk_main_iteration_do(FALSE) ?
Voilà le bout de code qui selon moi et selon la doc devrait fonctionner, si vous avez une idée de pourquoi ça gèle...!? Et est-ce crado (càd lent) comme solution? Je précise que la dépréciation de thread_enter/thread_leave est une grosse perte pour nous, car certains worker thread accèdent à la GUI en écriture puis en lecture un peu plus loin dans la même fonction. C'est une grosse galère de tout passer en asynchrone, thread_enter/thread_leave permettait de tout faire en synchrone, quitte à attendre que la GUI soit dispo, ce qui n'était pas un problème. C'est d'ailleurs ce que fait la classe GThreadLock ci-dessous. On la met au début du bloc de code à protéger, et le tour est joué!
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
class GThreadMutex
{
public:
Glib::Threads::Mutex GUI;
Glib::Threads::Cond GUICond;
Glib::Threads::Mutex myCode;
Glib::Threads::Cond myCodeCond;
};
class GThreadLock : public GThreadMutex
{
public:
GThreadLock();
~GThreadLock();
}; |
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
// execution dans le thread A (GUI)
gboolean giveMeAGo(void* data) {
GThreadMutex *threadMutex = static_cast<GThreadMutex*>(data);
Glib::Threads::Mutex::Lock lock(threadMutex->GUI);
threadMutex->myCodeCond.signal(); // execution du code protege dans le thread B
threadMutex->GUICond.wait(threadMutex->GUI); // attend la fin de l'éxecution du code dans le thread B
return false;
}
// instanciation dans le thread B
GThreadLock::GThreadLock() {
Glib::Threads::Mutex::Lock lock(myCode);
gdk_threads_add_idle(giveMeAGo, this);
myCodeCond.wait(myCode);
}
GThreadLock::~GThreadLock() {
Glib::Threads::Mutex::Lock lock(GUI);
GUICond.signal();
} |