Question
Implement a lock that may be held concurrently by many threads only when they request the same mode. A different mode waits until all current holders release. Then add fairness across queued modes.
```python
class ModalLock:
def try_acquire(self, tid: int, mode: str) -> bool: ...
def release(self, mode: str) -> list[int]: ...
class FairModalLock(ModalLock): ...
```
## Requirements
- `try_acquire` grants immediately or queues `(tid, mode)` without duplicates.
- `release` releases one holder of that mode and returns newly granted thread IDs.
- Base lock may admit a new same-mode requester while that mode is active.
- Fair lock prevents barging once another mode is queued.
- When the next queued mode becomes eligible, grant the contiguous batch already waiting for that mode.
- Reject invalid releases and define per-thread ownership.
## Follow-ups
1. Implement blocking `acquire` with a condition variable.
2. Compare FIFO batching, writer priority, and starvation risk.
3. Add timeout and cancellation of queued requests.
4. Support reentrancy or mode upgrades and explain deadlock risks.