LINUX.ORG.RU

Thread-safe аналог libcurl


0

0

Я делаю небольшую библиотеку, которая кроме всего прочего должна уметь получать данные с HTTP(s)-сервера. Сейчас для этих целей используется libcurl, но у неё могут возникнуть проблемы с потокобезопасностью и конфликт с другими библиотеками. Проблемы я нашёл три:

1) Если какой-то другой поток в библиотеке одновременно с моим вызовет curl_global_init или curl_global_init_mem, то может случиться жопа.

2) Если кто-то вызвал curl_global_init/curl_global_init_mem без флага CURL_GLOBAL_SSL до того как моя библиотека вызвала их с этим флагом, то SSL не будет инициализирован.

3) Проблема, похожая на 2, но только в curl_global_init_mem и для коллбэков.

Так что вопрос: есть ли какой-нибудь аналог libcurl, такой же простой в использовании но без подобной глобально-статической фигни? Обязательна поддержка SSL (HTTPs) и кроссплатформенность (*nix + win).

P.S. libwww - крайний случай, т.к. сильно сложно, плохо документировано и черезчур круто для моих задач.

Deleted

из названий curl_global_init и curl_global_init_mem смею предположить, что их достаточно инициализировать только в родителе и один раз. ман не смотрел :) просто интуитивно. могу ошибаться.

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

>> ну оберните обращения к curl в свой врапер и сереализуйте их через мьютекс.

Вы видимо неправильно поняли проблему.

Представьте вот такую схему:

libcurl.so -> libmyplugin.so -> someapp <- libotherplugin.so <- libcurl.so

Моя библиотека - это libmyplugin.so. Возможен вот такой сценарий:

1) someapp загружает libotherplugin.so
2) libotherplugin.so вызывает curl_global_init_mem и устанавливает свои коллбэки
3) someapp загружает libmyplugin.so
4) libmyplugin.so вызывает curl_global_init с дефолтными коллбэками,
libcurl видит что внутренние структуры уже инициализированы,
возвращает CURL_OK и ничего не делает
5) someapp выгружает libotherplugin.so
6) libmyplugin.so что-то пытается сделать с libcurl и это ведёт к
вызову коллбэков из уже выгруженного модуля libotherplugin.so
7) жопа

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

>> из названий curl_global_init и curl_global_init_mem смею предположить, что их достаточно инициализировать только в родителе и один раз. ман не смотрел :) просто интуитивно. могу ошибаться.

Это действительно так. Но "в родителе" я вызвать их не могу, так как я пишу только библиотеку для его плагина. Изменять код этого самого родителя и всех других возможных его плагинов я не могу.

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

>6) libmyplugin.so что-то пытается сделать с libcurl и это ведёт к вызову коллбэков из уже выгруженного модуля libotherplugin.so

здесь тогда нужно девелоперам libcurl'a руки оторвать за неотработку NULL'овых колбеков. если дают возможность колбека, то и должны проверить наличие этого самомго колбека.

а вторым шагом, надо руки оторвать девелоперам libotherplugin, которые за собой не "смывают".

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

> 5) someapp выгружает libotherplugin.so

5.1) libotherplugin.so перед выгрузкой освобождает занятые им ресурсы и в том числе дерегистрирует свои калбеки. в противном случае, тут уже ничем не поможешь - broken by design.

> 6) libmyplugin.so что-то пытается сделать с libcurl и это ведёт к
вызову коллбэков из уже выгруженного модуля libotherplugin.so
> 7) жопа

// wbr

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

да, забыл предложить... как "прокладку" можешь сделать так: переустанавливаешь эти колбеки на свои, и при каждом вызове этих колбеков делаешь проверку на присутствие предыдущих колбеков, если есть, то вызываешь их, еже ли нет - игноришь.

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

> переустанавливаешь эти колбеки на свои, и при каждом вызове этих колбеков делаешь проверку на присутствие предыдущих колбеков, (...)

..и говоришь "Welcome race condition".

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

Предлагаются варианты:

0. форкнуть libcurl, подпилить её по месту

1. форкнуть процесс, инициализировать libcurl в потомке, общаться с потомком по пайпу (мы вам url, вы нам содержимое). Случай беспорядочных внешних связей не рассматривается.

2. написать в документации, что libmyplugin.so нельзя загружать вместе с любым libotherplugin.so, использующим libcurl. Иначе ж-па.

3. всё-таки взять другую либу, или написать свою.

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

>..и говоришь "Welcome race condition".

Потому и написал - <<как "прокладку" можешь сделать так:>>

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

>> 5.1) libotherplugin.so перед выгрузкой освобождает занятые им ресурсы и в том числе дерегистрирует свои калбеки. в противном случае, тут уже ничем не поможешь - broken by design.

Design у libcurl действительно чуток broken =). Об описанных мной проблемах есть информация в man libcurl. Там рекомендуют вызывать curl_global_init(CURL_GLOBAL_ALL) и не рекомендуюется использовать что-то отличное от CURL_GLOBAL_ALL и вызывать curl_global_init_mem. Так что проблемы могут возникнуть только если гипотетический сторонний плагин не следовал этим рекомендациям.

А вообще, это всё у меня от недосыпа. Вероятность проявления этих *особенностей* libcurl в реальной жизни сильно меньше 0.01% =).

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

если таки есть необходимость плотно
использовать курл, тогда все равно придеться
лезть в него и допиливать по мере надобности

IMHO из своей обширной личной практики работы с курлом

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