1# Test that locks work when cancelling multiple waiters on the lock
2
3try:
4    import uasyncio as asyncio
5except ImportError:
6    try:
7        import asyncio
8    except ImportError:
9        print("SKIP")
10        raise SystemExit
11
12
13async def task(i, lock, lock_flag):
14    print("task", i, "start")
15    try:
16        await lock.acquire()
17    except asyncio.CancelledError:
18        print("task", i, "cancel")
19        return
20    print("task", i, "lock_flag", lock_flag[0])
21    lock_flag[0] = True
22    await asyncio.sleep(0)
23    lock.release()
24    lock_flag[0] = False
25    print("task", i, "done")
26
27
28async def main():
29    # Create a lock and acquire it so the tasks below must wait
30    lock = asyncio.Lock()
31    await lock.acquire()
32    lock_flag = [True]
33
34    # Create 4 tasks and let them all run
35    t0 = asyncio.create_task(task(0, lock, lock_flag))
36    t1 = asyncio.create_task(task(1, lock, lock_flag))
37    t2 = asyncio.create_task(task(2, lock, lock_flag))
38    t3 = asyncio.create_task(task(3, lock, lock_flag))
39    await asyncio.sleep(0)
40
41    # Cancel 2 of the tasks (which are waiting on the lock) and release the lock
42    t1.cancel()
43    t2.cancel()
44    lock.release()
45    lock_flag[0] = False
46
47    # Let the tasks run to completion
48    for _ in range(4):
49        await asyncio.sleep(0)
50
51    # The locke should be unlocked
52    print(lock.locked())
53
54
55asyncio.run(main())
56