Как обойти дедлок в ntdll?
От: Basil2 Россия https://starostin.msk.ru
Дата: 03.02.20 16:37
Оценка:
Ситуация:

Есть наш код и сторонняя либа, оба С++.

Мы обращаемся к либе в потоке 1. Она, в свою очередь, сама создает поток 2 и делит с ним данные. Когда наш код в потоке 1 дергает код либы, тот приостанавливает поток 2, делает что-то с данными, и вновь разрешает выполнение потоку 2. Типа синхронизация, дешево и сердито.

Проблема:

Иногда поток 2 выделяет память. Это происходит через функцию рантайма __lock(). Если поток приостанавливают в этот момент, то он так и остается в лочке. Затем приостановивший его тред сам пытается выделить память, попадает в ту же __lock() и всё виснет намертво.

Вопрос:

Как этого можно избежать? Доступ к коду либы есть. Но сделать либе нормальную синхронизацию не представляется возможным, там много обмена данными и еще куча слипов по коду. Поэтому нельзя просто выкинуть SuspendThread. Отказаться от выделения памяти в потоках тоже нельзя, т.к. скриптовый язык и там куча этих выделений.

Единственное, что я вижу как решение — SuspendThread используется всего в двух используемых нами функциях. То есть если бы был способ проверить, что __lock() встала на лочку, можно было бы попробовать обождать с саспендом, пока та не освободиться.

Есть ли такой способ?

Может есть более удачные решения?
Проект Minimap Zoom — маппим кусочек экрана компа на планшет.
Проект Levelbuddy — играем в WoW за двух персонажей одновременно.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.