LINUX.ORG.RU

libevent и Windows

 ,


0

1

Решил попробовать портировать небольшую программу под Windows.

Программа интенсивно использует libevent в разных разрезах: реагирует на сигналы, асинхронно ловит UDP-пакеты и управляется http гуем.

Ничего не предвещало геморроя, после небольших фиксов все кросс-собралось mingw, запустилось в wine, но:

1. Веб-гуй начал вести себя странно. Какие-то странички (или там картинки) показываются нормально, какие-то залипают или вообще не показываются. Причем все совершенно непредсказуемо, при каждом запуске и в разных браузерах по-разному. Собрал для верности в Win-боксе обычным (не кросс) mingw. Эффект тот же. Морщил моск, потом додумался запустить tcpdump с -X и изумился. Оказывается, в http-ответе libevent выставляет в Content-Length какие-то невменяемые огромные цифры. Пытался с наскока постичь логику (мало ли, может они выводят uint64_t в какой-то неподходящий printf-спецификатор), бегло просмотрел исходники, ниасилел. Ну да ладно, выставил Content-Length вручную, вроде заработало. Да, пробовал libevent 1.4 и 2.1 - результат одинаковый. Собирать MSVC не пробовал

2. Для уведомления потоков программа использует тот же libevent. То есть в одном потоке подписываемся на событие «прилетает UDP», на событие «гуй/система уведомляет» и ждем чего-нибудь. Гуй или система из других потоков уведомляют записью в дескриптор. Очень удобно. Так вот, в Windows libevent использует select(), а он там умеет селектить только сокеты (не произвольные дескрипторы). То есть нужно создать пару сокетов на loopback-интерфейсе и уведомлять уже через них. Это типа официально рекомендованный путь. В то же время пишут, что есть фаерволы, которые блокируют все на интерфейсе закольцовки, и это не отключается

3. Программа внезапно начала крешиться на event_del(). Это, возможно, был уже баг в логике самой программы, но разбираться уже перехотелось, и осадок только усилился

В общем, остался в недоумении. Ну, то есть можно, наверное, как-то с этим жить, но кто его знает что там еще всплывет? Погуглил про альтернативы (для pure C) и вообще загрустил. Похоже, libevent это лучшее что есть и практически единственная внятная альтернатива - писать на родных API для каждой платформы?

Deleted

y not Glib/GIO?

anonymous
()

В то же время пишут, что есть фаерволы, которые блокируют все на интерфейсе закольцовки, и это не отключается

...

В общем, остался в недоумении.

Я тоже в недоумении. Как этой ОС вообще можно пользоваться?

По п.2 и 3: это скорее всего ошибки в логике программы, использующей libevent. п.3 - точно. Более того, раз есть ошибка п.3, поведение программы может быть сколь угодно непредсказуемым, так что радуйтесь, что она вообще хоть как-то работает. Такие ошибки обычно ловятся valgrind'ом.

Так вот, в Windows libevent использует select()

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

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

Glib/GIO

Вот в ихнем TODO пишут:

«I've done some work on win32, but this hasn't been tested or updated recently. Someone interested in win32 should look this over»

Похоже, там еще грустнее чем в libevent. И у него вроде бы нет httpd и обработки сигналов?

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

В whatsnew пишут что только select(): «Unfortunately, the main Windows backend is still select()-based». Ну и в коде, собственно. Да дело не в скорости, а в том что в Windows он умеет только события на сетевых сокетах. Хотя в WinAPI есть WaitForMultipleObjects, которая умеет даже больше чем POSIX select()

Впрочем, уже почти смирился с тем что придется писать вручную

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

У WaitForMultipleObjects, как я понимаю, есть ограничение на число одновременно прослушиваемых дескрипторов.

Но libevent 2.0 умеет использовать IOCP для объектов bufferevents (эти объекты в версии 2.0 и появились).

Кроме того, libevent умеет «слушать» таймауты.

Sorcerer ★★★★★
()

Под виндой нужно использовать IOCP

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