Как выглядят костыли в коде (#2)

Привет.

По свежим следам, добавлю сюда заметку про недавнее изменение в коде FB3.

Вдогонку

Вкратце о проблеме.

1. Есть объект со счетчиком ссылок (класс rem_port).
2. Этот объект управляется через смарт указатель. И, по идее, проблем быть не должно.
3. Тем не менее у него проблема с управлением времени жизни. Дважды удаляется в многопоточной среде.
4. Потому что конструктор rem_port, за каким-то …, вызывает addRef. И этот инкремент нужно где-то компенсировать однократным вызовом release.

Если я все правильно понял, багу заложили около 12 лет назад. Когда в rem_port добавили счетчик ссылок. Но это так, для ориентира.

Что делает этот патч. Он делает добавляет монопольность этого однократного вызова release.

	bool releasePort()
	{
		Firebird::RefMutexEnsureUnlock portGuard(*port_sync, FB_FUNCTION);
		const bool locked = portGuard.tryEnter();
		fb_assert(locked);

		fb_assert(!(port_flags & PORT_released));
		if (port_flags & PORT_released)
			return false;

		port_flags |= PORT_released;
		release();
		return true;
	}

При этом для блокировки он использует guard (*port_sync) и флаг (port_flags), которые находятся в самом защищаемом объекте.

Я считаю — это гениально.

Нет, правда, аплодирую стоя.

Leave a Comment