LINUX.ORG.RU

libfuse, треды и timerfd

 , , timerfd


2

2

до запуска fuse_main() создается тесколько тредов.

В каждом треде создаётся таймер через timerfd_create(CLOCK_REALTIME, 0)

далее делаем timerfd_settime(tfd, TFD_TIMER_ABSTIME,...)

таймер через 2 секунды и интервал 2 секунды.

все работает!

как только запускается fuse_main() в виде демона, то все чтение из tfd прекращается.

Что это за @#$%^&*! ?

★★★★★
Ответ на: комментарий от deep-purple

Что оно маскирует?

В какую сторону смотреть ?

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

Оно выполняет read() из timerfd

А какое возвращаемое значение у read? Должно быть sizeof(uint64_t), т.е. 8

Ощущение, что libfuse что-то маскирует (сигналы?)

timerfd как бы к сигналам не имеет отношения

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

А какое возвращаемое значение у read? Должно быть sizeof(uint64_t), т.е. 8

Да!

timerfd как бы к сигналам не имеет отношения

я тоже так думал!

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

Если read из timerfd продолжает вызываться и возвращать 8, значит проблема не в timerfd, а в тех действиях, которые происходят после read.

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

Тред раз в N секунд читает данные из procfs (fopen(),fgets(),fclose())

Если запускаю с "-f" то все работает.

Если без него, то работает ровно до того момента, как запускается fuse_main()

Я пробовал вставлять задержку между запуска треда и запуском fuse_main().

чтение из timerfd не завершается после запуска fuse_main().

Другой глюк - вызов в треде sleep() тоже умирает при запуске fuse_main() :(

Ядро 5.4.17, glibc-2.29, libfuse-2.9

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

Если read из timerfd продолжает вызываться и возвращать 8, значит проблема не в timerfd, а в тех действиях, которые происходят после read.

оно из read() не возвращается!

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

К сигналам имеет отношение alarm(2) - неудобный, примитивный и низкопроизводительный способ заставить ядро обеспечить твой код таймерами

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

А fuse_main делает какие-то подозрительные системные вызовы, например с использованием fd твоих таймеров?

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

Ага!

Я посмотрел в /proc/<pid>/fdinfo/*

Разница в состоянии таймера есть.

Полное ощущение, что заблокирован какой-то сигнал (SIGAIO)

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

Полное ощущение, что заблокирован какой-то сигнал

Если что-то такое имеет место, в strace должен быть вызов sigprocmask или signal во время fuse_main

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

А fuse_main делает какие-то подозрительные системные вызовы, например с использованием fd твоих таймеров?

Я думаю, что нет.

Как еще в треде сделать паузу? select() ?

Я хочу попробовать создать timerfd после fuse_main()

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

Если что-то такое имеет место, в strace должен быть вызов sigprocmask или signal во время fuse_main

Хм. Это должно быть видно в /proc/<pid>/status

Нужно посмотреть.

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

Как еще в треде сделать паузу? select() ?

Как вариант

Еще можно запустить программу в gdb, поставить бряк на fuse_main, а когда остановится, сделать catch syscall - будет останавливаться на любом ситемном вызове и можно разобраться, что там происходит

annulen ★★★★★
()

У тебя fuse_main() форкается? Если не запрашиваешь foreground режим специально, то он точно зовёт fork(). Если у тебя так и есть, считай, что все остальные треды умерли. Потому что они умерли. Все.

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

У тебя fuse_main() форкается? Если не запрашиваешь foreground режим специально, то он точно зовёт fork().

Я этого не знал, но по-умолчанию включал в "подозрительные системные вызовы в strace. Что-что, а fork сложно пропустить.

annulen ★★★★★
()
Ответ на: комментарий от i-rinat

Похоже!

А как с этим бороться ?

В исходники libfuse лезть, чтоб узнать, где можно что-то сделать после fork()?

Может проще самому сначала форкнуться, а libfuse указать ключик '-f' ?

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

fork() был ожидаемым вызовом.

А вот то, что треды при форке киляются, не знал, хотя это логично.

Не часто приходится кодить с тредами...

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

В fuse_operations есть колбек init(). Может, инициализацию положить туда?

Да похоже, что это самое подходящее место!

Спасибо!

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

А вот то, что треды при форке киляются, не знал, хотя это логично.

Они не килляются, просто форкается лишь тот поток, который запустил fork(), см. https://linux.die.net/man/3/pthread_atfork

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