LINUX.ORG.RU
ФорумTalks

Red Hat угощает Wayland-ом разработчиков Firefox

 


0

5

Мартин Странски из Red Hat написал Wayland-Proxy как C++-версию предыдущей экспериментальной концепции, написанной на Rust

Среди ошибок Firefox Wayland одна из самых распространенных ошибок связана с потерей соединения с компоновщиком Wayland. Чтобы справиться с этим, необходимо иметь прокси-сервер между Firefox и компоновщиком Wayland для кэширования сообщений и предотвращения переполнения очереди сообщений компоновщика.

В комментариях разбирают подробнее

Mutter (и, возможно, другие) завершает работу клиента Wayland, если он распознается как зависший. Обычно это означает, что клиент Wayland недостаточно быстро читает сообщения из сокета дисплея Wayland и буфера вывода сообщений компоновщика. заполнено. Это может быть ошибка в самом приложении (цикл событий не обрабатывается) или это вызвано устройствами ввода, такими как мышь с частотой 1000 Гц, которая генерирует слишком много событий.

Такая ошибка действительно есть, любители Wayland с высокой герцовкой мыши, ранее делились советами не двигать мышкой когда открыт Firefox, иначе это может немедленно привести к его закрытию.

https://www.phoronix.com/news/Wayland-Proxy-Firefox

★★★★★
Ответ на: комментарий от cumvillain

Послать WM_PAINT ещё раз и проблема решена. Содержимое окон в Windows не персистентно с самого начала времён и ОС в любой момент может запросить перерисовать содержимое.

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

Послать WM_PAINT ещё раз и проблема решена. Содержимое окон в Windows не персистентно с самого начала времён и ОС в любой момент может запросить перерисовать содержимое.

Не, не решена. Потому что чтобы записать в поверхность, эта поверхность должна быть известна драйверу.

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

У программ может быть больше одного окна и у них будет одинаковый app_id.

Зато title будет разный. Короче, это не проблема.

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

Это происходит полностью прозрачно для клиентов. Состояние окон не теряется. Пересоздавать никаких соединений не надо.

Это вот совсем не так. В винде, как раз, в кажное окно прилетает device_lost, и окна, кто как умеет, воссоздают свой стейт. Какой-нибудь «проводник» можно свернуть/развернуть, какие-нибудь поделки на электроне проще перезапустить.

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

В винде, как раз, в кажное окно прилетает device_lost

Это касается только Direct3D/OpenGL/Vulkan. Программам на GDI нет дела до device_lost.

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

Это касается только Direct3D/OpenGL/Vulkan. Программам на GDI нет дела до device_lost.

Т.е. всех современных программ. Потому что я даже PDF’ку без Vulkan уже смотреть не могу из-за DPI.

cumvillain
()
Последнее исправление: cumvillain (всего исправлений: 1)
Ответ на: комментарий от X512

Не надо ничего копить. Достаточно хранить два состояния: состояние ввода клиента на момент зависания и состояние ввода сервера. При развисании достаточно передать только разницу между двумя этими состояниями.

Это так не работает. Получим потерю информации: например, это игра, и перемещения мыши имеют значение не только в плане финальной точки её пути.

Rootlexx ★★★★★
()
Ответ на: комментарий от cumvillain

Зачем тебе Vulkan? GDI поддерживает HiDPI. К тому же перезапуск драйвера у меня переживали вообще все приложения, только с играми не видел как это работает. С браузером у меня нормально все было.

MOPKOBKA ★★★★★
() автор топика
Последнее исправление: MOPKOBKA (всего исправлений: 1)
Ответ на: комментарий от Rootlexx

Нету другого выхода кроме как терять промежуточные положения если клиент не может достаточно быстро обрабатывать события.

X512 ★★★★★
()
Ответ на: комментарий от MOPKOBKA

Зачем тебе Vulkan? GDI поддерживает HiDPI. К тому же перезапуск драйвера у меня переживали вообще все приложения, только с играми не видел как это работает. С браузером у меня нормально все было.

Затем чтобы оно рисовалось с нормальной скоростью. Софтварный рендеринг тормозит как сучка.

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

Нету другого выхода кроме как терять промежуточные положения если клиент не может достаточно быстро обрабатывать события.

Предположим, что последовательность ивентов такая:

wl_iface.new()
wl_iface.attr1()
wl_iface.attr2()
wl_iface.attr3()
wl_iface.done()

Дроп любого из этих ивентов означает что стейт продолбан. Что делать?

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

Использовать объект на стороне сервера хранящий состояние. После развисания отправлять разницу между последним состоянием на момент зависания и текущим состоянием сервера. Метод хранения состояния зависит от типа конкретного состояния, например для клавиатуры это будет битовое поле нажатых клавиш.

Генератор событий не вызывает интерфейсы Wayland напрямую, вместо этого он обновляет объект состояния, а тот уже генерирует Wayland события.

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 1)
Ответ на: комментарий от X512

Использовать объект на стороне сервера хранящий состояние. После развисания отправлять разницу между последним состоянием на момент зависания и текущим состоянием сервера. Метод хранения состояния зависит от типа конкретного состояния, например для клавиатуры это будет битовое поле нажатых клавиш.

Ну вот он развис, вернулся, и снова завис посередине этой последовательности. Если дропнем – приложение потеряет стейт. Если не дропнем – получим бесконечную буферизацию на стороне сервера (что, откровенно говоря, не то чтобы большая проблема).

Алсо там уже приводили примеры в тикете: каким-то приложениям (планшетному софту, например) требуется весь путь мышки, а не только результирующее состояние.

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

Ну вот он развис, вернулся, и снова завис посередине этой последовательности.

Это не проблема если обрабатывать каждого клиента в отдельном потоке. Можно и в одном потоке без блокировок, но тогда код будет запутаннее. Например можно дождаться когда кольцевой буфер будет пуст и только тогда генерировать последовательность событий. Последовательности разбить на атомарные группы которые гарантированно влезают в кольцевой буфер.

Алсо там уже приводили примеры в тикете: каким-то приложениям (планшетному софту, например) требуется весь путь мышки

По вашему прибить такой софт будет лучше? Опять повторяю если клиент обрабатывет события медленнее их генерации, то неизбежно придётся пропускать события. Если втекает больше чем вытекает, то вода польётся из краёв. Математика младшей школы.

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

Нету другого выхода кроме как терять промежуточные положения если клиент не может достаточно быстро обрабатывать события.

Так нельзя делать.

Например, имеем форму с флагом «Не удалять файлы» и кнопкой OK. Пользователь щёлкнул по флагу, а затем по OK. Если сквошить события и отправлять только финальное состояние, то щелчок по флагу будет проигнорирован и файлы будут удалены, несмотря на то что пользователь явно ткнул «Не удалять» — получим потерю данных.

Графическая система не имеет ни малейшего понятия о том, как клиент проинтерпретировал бы события, которые она дропнула, а значит, она не имеет права это делать.

В этом случае варианта 2:

  1. Копить события бесконечно — см. пример с OOM.

  2. Задать верхнюю границу числа необработанных событий.

    Это самый адекватный вариант. Проблема с Firefox, когда эта граница достигается при условно нормальных условиях использования, означает лишь, что выбранный размер буфера слишком мал и должен быть увеличен, вот и всё.

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

Графическая система не имеет ни малейшего понятия о том, как клиент проинтерпретировал бы события, которые она дропнула, а значит, она не имеет права это делать.

В Windows события мыши вообще генерируются ленивым образом в момент чтения без очерели и ничего. Что-то не слышал криков что не та кнопка нажалась и всё удалилось.

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

В Windows события мыши вообще генерируются ленивым образом в момент чтения без очерели и ничего. Что-то не слышал криков что не та кнопка нажалась и всё удалилось.

Anecdotal evidence.

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

И? Не вижу смысла решения статистически незначимых абстрактных проблем в вакууме. А вот падения программ от движения мышью – это реальная серьёзная проблема приводящая к потере данных.

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

По вашему прибить такой софт будет лучше? Опять повторяю если клиент обрабатывет события медленнее их генерации, то неизбежно придётся пропускать события. Если втекает больше чем вытекает, то вода польётся из краёв. Математика младшей школы.

По-моему надо сделать то что сделано в Xorg, при этом дав композитору возможность ограничить размер очереди сверху. Собственно, кто-то уже даже патч сделал.

cumvillain
()
Последнее исправление: cumvillain (всего исправлений: 1)
Ответ на: комментарий от Rootlexx

Пользователь щёлкнул по флагу, а затем по OK.

Так флаг же не загорится, никто не нажмет после этого кнопку ОК.

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

На «стоимость» M:N тредов это не влияло.

M:N тредов? Если ты про async/коротины и прочий блуд, то там там та же проблема – заблокировался на сисколе, застрял весь тред.

Но на самом деле неважно в каком потоке блокироваться, потому что блокирование просто уносит проблему на уровень выше – ивенты не перестают генерироваться.

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

А, ещё у 2.4 - 2.6 солярки так было, но потом забили.

В результате такой «предвестник» nginx-а как oops proxy роскошно обслуживал дофига соединений тредами. Но только на солярке и freebsd.

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

В результате такой «предвестник» nginx-а как oops proxy роскошно обслуживал дофига соединений тредами. Но только на солярке и freebsd.

Просто тогда у всех было разное понятие что такое треды :))

Сейчас треды это системные треды, а асинхронка это библиотека в твоем любимом языке. И все счастливы.

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

Для обработки логики отправки событий Wayland короутины тоже подойдут.

А теперь расскажи мне, пожалуйста, где разница между списком ивентов и списком тасок.

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

Разница в том что проще писать логику когда любая отправка сообщения может заблокироваться. Очередь переполнилась -> переключает на другой поток/коротину.

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

Разница в том что проще писать логику когда любая отправка сообщения может заблокироваться. Очередь переполнилась -> переключает на другой поток/коротину.

Чем это отличается от ресайза очереди ивентов-то? :D

cumvillain
()
Последнее исправление: cumvillain (всего исправлений: 1)
Ответ на: комментарий от cumvillain

В том, что очередь в принципе не может переполнится и нет риска OOM. Сообщения зависшим клиентам перестают отправляться и после развисания передаётся только разница по состоянию на момент зависания с пропуском промежуточных состояний.

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

В том, что очередь в принципе не может переполнится и нет риска OOM. Сообщения зависшим клиентам перестают отправляться и после развисания передаётся только разница по состоянию на момент зависания с пропуском промежуточных состояний.

И что тебе мешает дропать ивенты? :D

Ты все никак не можешь понять что проблема здесь не в механизме доставке (синхронный / асинхронный), а в том, можно ли терять ивенты или нет. Если бы их можно было терять, можно было бы просто дропать их при переполнении ринга, вместо закрытия коннекшона. Но как мы уже выяснили, дропать их нельзя, потому что лезет куча корнеркейсов. И самое простое – тупо их буферизировать, как это делал xserver.

cumvillain
()
Последнее исправление: cumvillain (всего исправлений: 2)
Ответ на: комментарий от X512

События всегда можно дропать, если делать это по умному сохраняя консистентность.

Это значит что нужен Ещё Один Протокол, который теперь позволит сливать с сервера стейт. Кажется что проще просто ринг побольше сделать :D

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

Не надо ничего сливать. Сервер может реконструировать состояние которое видит клиент на момент зависания и послать разницу между этим состоянием и текущим состоянием. Ничего сложного в этом нет, нужен дополнительный слой между генератором событий и отправкой сообщений клиенту. Этот слой будет заниматься корректным пропуском событий в случае переполнения.

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

Не надо ничего сливать. Сервер может реконструировать состояние которое видит клиент на момент зависания и послать разницу между этим состоянием и текущим состоянием. Ничего сложного в этом нет, нужен дополнительный слой между генератором событий и отправкой сообщений клиенту. Этот слой будет заниматься корректным пропуском событий в случае переполнения.

В случае мышки это несколько тысяч записей её передвижения. Где разница с рингом-то?

cumvillain
()
Ответ на: комментарий от cumvillain
1. Нажали левую кнопку мыши
2. Клиент завис
3. Двинули курсор на 10, 20
4. Двинули курсор на 50, 40
...
100500. Двинули курсор на 150, 70
100501. Отпустили левую кнопку мыши
100502. Клиент развис
100503. Отправили клиенту отпускание левой кнопки мыши
100504. Отправили клиенту передвижение курсора на 150, 70

События 3-100499 пропущены.

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 1)
Ответ на: комментарий от X512

События 3-100499 пропущены.

Прекрасно! И чувак, который на планшете рисует, получает вместо линии точку. А кейс чувака с планшетом это, судя по баг-репорту, частый кейс.

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

Значит софт планшета должен научиться быстрее обрабатывать сообщения. Например он может собирать их в свой внутренний буфер.

Я если что не против увеличения размера кольцевого буфера, но очевидно что любой буфер можно переполнить и я резко против чтобы клиент падал в таком случае.

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 1)
Ответ на: комментарий от X512

Значит софт планшета должен научиться быстрее обрабатывать сообщения. Например он может собирать их в свой внутренний буфер.

Ага, а потом его выкидывает шедулер и он ничего уже не собирает. Короче, твоя попытка починить ломает кучу других кейсов, а динамический лимитированный ринг – не ломает.

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

а динамический лимитированный ринг – не ломает.

Применить обе стратегии одновременно кто мешает? И события не будут теряться в большинстве случаев, и программы падать не будут.

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

Применить обе стратегии одновременно кто мешает? И события не будут теряться в большинстве случаев, и программы падать не будут.

Тем что твоя требует кучу лишней разработки, а увеличение ринга не требует ничего.

cumvillain
()
Ответ на: комментарий от cumvillain
struct wl_ring_buffer {
-	char data[4096];
+	char* data;
	uint32_t head, tail;
+	uint32_t size_bits;
};

То, как это написано изначально - это какой-то рофл. Где же те «великие программисты», что пишут Wayland, который лучше чем Х?

PPP328 ★★★★★
()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)