LINUX.ORG.RU

Xlib: unexpected async reply (sequence 0x2a79)!


0

0

Есть проект (Qt, OpenGL, RH9), графики не шибко мноного ;). В процессе работы появляется ошибка Xlib: unexpected async reply (sequence 0x2a79)! после чего все виснет. подскажите, что это заначит! я уже замучалась! может чего доставить надо? с драйверами у меня все ok.


Я видел такие ошибки, если в Х-приложении использовать потоки (threads). Это происходит при одновременном вызове функций Xlib из разных потоков, что в Qt делать нельзя (и не только в Qt). Это один из возможных вариантов.

df_0903
()
Ответ на: комментарий от df_0903

Потоков действительно два. и оба они хотят X. но ситуация получается такая: под RH9 все вроде работает нормально, ошибок не вылезает. А вот в другой системе (кастрированный RH cо свом оконным менеджером) вылазит эта ошибка. Может быть дело в иксах?

Helena
() автор топика
Ответ на: комментарий от Helena

Увы, дело не в X. Я когда-то через это прошел. В man-страницах написано, что в многопоточных приложениях доступ к Xlib-функциям нужно или блокировать (черех mutex, например) или через явное программирование клиентов, т.е в каждом потоке делать XOpenDisplay и т.д. А Qt (да и другие аналоги тоже), насколько я знаю этого не делают. Ошибка такая возникает совершенно случайно. Программа может несколько дней работать, а затем сбойнуть.

df_0903
()
Ответ на: комментарий от df_0903

понятно. Спасибо большое!

придется туда засунуть мьютексы.

А вот такой вопрос - у меня перерисовка реализована в обработчике сигналов, т.е. когда дочерний поток хочет обновить картинку он посылает сигнал и перерисовка делается в обработчике. Это не аналогично использованию мьютекса?

Helena
() автор топика
Ответ на: комментарий от Helena

Так просто не скажешь. Если вы имеете ввиду сигналы Qt, то вряд ли получится. Даже через мьютексы. Очень сложно будет. А если системные сигналы, то в потоках они ведут себя странно. Тоже может не получится. Хотя не знаю, нужно пробовать. Мне в конце-концов пришлось отказаться от Qt и писать собственную библиотеку, основанную на Xlib.

df_0903
()
Ответ на: комментарий от df_0903

А у меня задача такая - написать на Qt. Использовала обычные системные сигналы и оно то работало, то нет... Наверное, здесь все зависит от того в чьем адресном пространстве выполняется обработчик сигнала... А может и нет...

Helena
() автор топика
Ответ на: комментарий от Helena

Можно попробовать pthread_kill c сигналом SIGUSR1 или SIGUSR2. Второй вариант, периодически (через таймер) проверять какой-либо флажок. А еще лучше отказаться от использования потока.

df_0903
()
Ответ на: комментарий от Helena

Я делал примерно так: void shandler1(int,siginfo_t*,void *) { //do something } ... void thread(void*) { int signo=SIGUSR1; struct sigaction saction_usr1; struct sigaction old_saction; saction_usr1.sa_handler=NULL; saction_usr1.sa_sigaction=shandler1; sigemptyset(&saction_usr1.sa_mask); #ifdef linux saction_usr1.sa_flags=SA_RESTART|SA_SIGINFO|SA_NOMASK; # else saction_usr1.sa_flags=SA_SIGINFO; #endif sigaddset(&saction_usr1.sa_mask,signo);

if(sigaction(signo,&saction_usr1,&old_saction)==-1) perror("thread sigaction"); ... } Такой вариант работает. Правда, я думаю, что в обработчике сигнала не стоит вызывать функции Qt, потому что это вроде прерывания.

df_0903
()
Ответ на: комментарий от df_0903

Спасибо.

Не очень поняла, зачем два sigaction (usr1 и old)? ведь обработчик сигналов все равно одни - shandler1()? >saction_usr1.sa_handler=NULL; saction_usr1.sa_sigaction=shandler1;

Думаю, вы имели в виду: saction_usr1.sa_handler=NULL; saction_old.sa_sigaction=shandler1; ;)

>if(sigaction(signo,&saction_usr1,&old_saction)==-1) perror("thread sigaction"); ... }

По-моему, можно было написать sigaction(signo, &saction_usr1, NULL). Или я чего не понимаю?

а в остальном у меня сделано также, и оно неработает так как я описывала...:(

>Правда, я думаю, что в обработчике сигнала не стоит вызывать функции Qt, потому что это вроде прерывания.

а где же их тогда в многопотоковом приложении писать?

Helena
() автор топика
Ответ на: комментарий от Helena

old_saction нужен для сохранения старого значения.

По поводу обработчика. Лучше всего выставлять переменную-флажок и проверять ее периодически через таймер. Вообще-то трудно советовать не зная конкретной задачи. Можно еще попробовать через XSendEvent. В этом случае нужно через Xlib открывать соединение с X-сервером и т.д:

Display* dpy=XOpenDisplay(NULL); ... XEvent ev;

//initialize ev with needed params

XSendEvent(xdpy,WinId,False,0,&ev);

...

df_0903
()
Ответ на: комментарий от df_0903

Спасибо огромное за мудрые советы!

Helena
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.