Nikita
транк clang'а хавает
Nikita
пади баг какой то
Alexander "SonnySlave"
мб-мб
Nikita
студийный вообще какую то дичь пишет
Nikita
такое ощущение что он deduction guides не понмиает
Nikita
/std:c++latest вроде указал
Stanislav
на годболте студия версии 15.0, без апдейтов. Последняя версия если что 15.6
Nikita
Nikita
это он обманывает тип?
Stanislav
не очень то и обманывает
Stanislav
Stanislav
у компилера есть своя версия
Nikita
аа
Nikita
понял
Nikita
15 подумал как 2015
Stanislav
19.10.25017 это соостветствует как раз 15.0 или 15.1
Stanislav
Nikita дай пример проверю на последних версиях)
Nikita
#include <type_traits>
namespace foo
{
template<typename T>
struct Foo
{
template<typename... Args>
Foo(Args&&...)
{
}
};
template<typename T, typename... Ts>
Foo(T&&, Ts&&...) -> Foo<std::remove_reference_t<T>>;
}
int main()
{
using namespace foo;
Foo{1, 2, 3, 4};
}
Matwey
Похоже, что действительно хендлеры вызываются после вызова cancel().
Matwey
Ну, т.е. не гарантируется, что во время.
Stanislav
Nikita
ну значит судя по всему баг clang'a 5 и 6 версий
Berkus
Stanislav
Extend template argument deduction for functions to constructors of template classes – when you construct a class template you no longer have to specify the arguments.
Berkus
Matwey
Ну и хорошо
Berkus
потому что никто не может гарантировать когда именно этот хендлер исполнится и кто еще будет жив
Matwey
http://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/reference/async_read_until/overload5.html
Вот нашел тёмный угол на мой вкус. Утверждается, что
A streambuf object into which the data will be read. Ownership of the streambuf is retained by the caller, which must guarantee that it remains valid until the handler is called. Вполне законное требование, учитывая, что функция принимает ссылку на объект, которой затем пользуется в неясный момент времени. Но на мой вкус тут логичнее было бы гарантировать until the handler is called or operation is cancelled. Потому-что мы поняли, что эти две ситуации не всегда совпадают во времени, а после отмены операции ей уж точно не нужны ресурсы. И вот неясно, это небрежность в документации или какие-то темные углы реализации которые я не улавливаю.
Berkus
Berkus
в случае cancellation он ТОЖЕ вызывается
Matwey
Да
Matwey
Вопрос не в этом же
Berkus
ну поэтому хендлер должен гарантировать что к выполнению хендлера память никуда не делась
Berkus
> И вот неясно, это небрежность в документации или какие-то темные углы реализации которые я не улавливаю.
там просто очень хуевая документация, очень, даже вместе с think-async.com и beast все равно очень сложно разбираться
Matwey
Сначала я инициирую отмену операции, а затем спустя какое-то время вызывается хендлер. Память хендлера никуда не денется, он отдается внутрь копированием/перемещением. Речь идет сейчас про буфер, который отдается по ссылке. На мой взгляд, меня заставляют гарантировать его сохранность в тонкий промежуток времени между тем как я отменил операцию (а гарантируется, что операция будет immediately cancelled) и тем, как вызвался хендлер (в соответствии с exactly one time).
Berkus
Matwey
потому что пока ты ожидаешь отмены, операция ОС может выполниться и записать в буфер что-то. Приходящие из ОС события ты никак не контролируешь, если освободишь память - перезапишется что-то еще.
Что значит "ожидаешь"? Я конечно не претендую на то, чтобы быть носителем английского, но operations to finish immediately (как сказано в документации) означает что операция будет отменена немедленно, если бы надо было чего-то ожидать, то было бы сказано operations to finish eventually. ОС тут не причем, по той простой причине, что есть разница между получением события "доступны данные" и его обработкой, т.е. актуальным чтением (когда нужен буфер И после которого планируется выполнение хендлера). Между ними нужно еще отобразить файловый дескриптор ОС во внутреннюю структуру бустов, чтобы понять, что чтение вообще заказывали. Так как действует правило одного вызова хендлера, значит boost asio при вызове отмены операции способен различить две ситуации: 1) отмена вызвана до непосредственной обработки операции 2) отмена вызвана после непосредственной обработки и вызов хендлера уже запланирован. Во втором случае, очевидно, ссылка на буфер уже не нужна кишкам asio (будем считать, что мы туда не ходим из хендлера).. В первом случае, нет никакой проблемы атомарно выкинуть запрошенную операцию из списка и таким образом отменить реальное чтение данных..
Berkus
Что значит "ожидаешь"? Я конечно не претендую на то, чтобы быть носителем английского, но operations to finish immediately (как сказано в документации) означает что операция будет отменена немедленно, если бы надо было чего-то ожидать, то было бы сказано operations to finish eventually. ОС тут не причем, по той простой причине, что есть разница между получением события "доступны данные" и его обработкой, т.е. актуальным чтением (когда нужен буфер И после которого планируется выполнение хендлера). Между ними нужно еще отобразить файловый дескриптор ОС во внутреннюю структуру бустов, чтобы понять, что чтение вообще заказывали. Так как действует правило одного вызова хендлера, значит boost asio при вызове отмены операции способен различить две ситуации: 1) отмена вызвана до непосредственной обработки операции 2) отмена вызвана после непосредственной обработки и вызов хендлера уже запланирован. Во втором случае, очевидно, ссылка на буфер уже не нужна кишкам asio (будем считать, что мы туда не ходим из хендлера).. В первом случае, нет никакой проблемы атомарно выкинуть запрошенную операцию из списка и таким образом отменить реальное чтение данных..
ну ну
Berkus
вот тебе простой пример
тред а запускает вызов read()
thread b делает cancel()
Matwey
И? Я подозреваю что read() внутри сделан через async_read() и ожидания на семафоре, который отпускается соответствующим хендлером.
Matwey
Короче, я смотрю реализацию impl/select_reactor.ipp и там всё как я сказал - операции хранятся в очереди, все обращения к которой защищены мьютексом, а операция просто cancel_ops удаляет из очередей релевантные операции. Так что операция из очереди в любом случае атомарно пропадет, либо во время cancel_ops(), либо после вызова select() внутри run(), когда произойдет релевантное событие в ОС.
Dmitry
https://github.com/cpp-netlib/uri/tree/master/src/boost
Dmitry
зацените 3дпати
Ostap ꑭ
Top 10 Bugs in the C++ Projects of 2017 – Sergey Vasiliev – Medium
https://medium.com/@CPP_Coder/top-10-bugs-in-the-c-projects-of-2017-d7e48a5c23b2
Dmitry
буста много не бывает
Alexander "SonnySlave"
да, что ж поделать, что люди не переделали ещё на пакетный менеджер какой-нибудь
Berkus
Berkus
Matwey
ну да, select() много в буфера записывает....
Если будет операция в очереди, то ::read() запишет в буфер и выкинет операцию из очереди. А если не будет в очереди (отмена сработала раньше, чем `select()`), то и не будет.записывать.
Matwey
По-моему все хорошо получается.
Berkus
Berkus
вот тогда получится хорошо
Matwey
Вместе они случится не могут, они оба защищены одним мьютексом. Если отмена срабатывает после read(), тогда она просто ничего не делает. Операция уже была обработана, и всё, что от неё осталось, это хендлер, который ожидает в очереди на запуск и будет когда-нибудь потом запущен.
Berkus
Berkus
я свою дозу фиксов за аналогичными матвеями не врубающимися в асинхронные евенты от ОС уже получил, спасибо
Berkus
бектрейсы эти знаю наизусть
kitsu
есть какой-нибудь норм способ остановить rxcpp timer на отдельном треде?
Constantine
короче, дискардить можно только события, которые происходят в том же потоке, что и дискардятся
Constantine
Ighor
size_t encode(uint8_t buf[static 9], uint64_t num)
Berkus
а что там,
~buffer_owner() {
if (has_pending_io())
discard_pending_io();
}
?
ну там такое плюс еще попытки синхронизации внешнего IO с помощью эээ не знаю как это назвать, но они короче изобрели новый тип данных состоящий из атомик счетчика под кондваром (похоже на шаред птр, м?) и который должен каким-то образом помочь принудительно удалить буфера даже если в них кто-то пытается записать. я говорю - ну чуваки, шаред_птр на стейт и держите его в лямбде, станет ненужно - освободите, гарантия асио на ровно один вызов хендлера специально для этого и придумана. они: неет, шаред птр плохо мы не можем контролировать время жизни объектов. программа: SIGSEGV in shutdown().
такое
Александр
я тут выяснил, что при наличии бинарной совместимости, polymorphic allocator позволяет не отстреливать себе ноги при передаче контейнеров в dll, например
Александр
навеяно вот этим:
https://stackoverflow.com/a/35311928/7410750
Constantine
Constantine
Berkus
когда чуваки в 1997 написали софт и забыли его обновлять
Berkus
а с новой CRT оно не работает )
Constantine
Constantine
Stanislav
Constantine
зачем?
Berkus