🚦 Структура семафора SemLockObject, в реализации модуля multiprocessing, поддерживает внутреннее поле счетчика count. При работе в качестве рекурсивного мьютекса (RECURSIVE_MUTEX) count — это количество раз, когда поток захватывал мьютекс (т. е. 0, 1, .. N). А при работе в качестве семафора (SEMAPHORE) счетчик часто равен 0 или 1, но может быть отрицательным, если SemLockObject инициализируется с maxvalue > 1.
🔄 Изменение count не является потокобезопасным без GIL внутри процесса. Обратите внимание, что поле count не является общим для всех процессов, в отличие от базового поля sem_t или HANDLE.
☠️ В частности, в этом коде изменение count, после освобождения семафора, не является потокобезопасным без GIL: ⛔️ Это может быть источником взаимоблокировок при работе с отключенным GIL.
💁♂️ Кажется немного странным вставлять блокировку в реализацию блокировки, но на удивление сложно сделать так, чтобы изменения считались потокобезопасными, особенно в случае использования kind == SEMA