8000 extmod/uasyncio: Fix Lock when cancelling a task with pending acquire. · micropython/micropython@07a3ff3 · GitHub
[go: up one dir, main page]

Skip to content

Commit 07a3ff3

Browse files
committed
extmod/uasyncio: Fix Lock when cancelling a task with pending acquire.
1 parent ebad375 commit 07a3ff3

File tree

1 file changed

+16
-11
lines changed

1 file changed

+16
-11
lines changed

extmod/uasyncio/lock.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,39 +6,44 @@
66
# Lock class for primitive mutex capability
77
class Lock:
88
def __init__(self):
9-
self.state = 0 # 0=unlocked; 1=unlocked but waiting task pending resume; 2=locked
10-
self.waiting = core.TaskQueue() # Queue of Tasks waiting to acquire this Lock
9+
# The state can take the following values:
10+
# - 0: unlocked
11+
# - 1: locked
12+
# - <Task>: unlocked but this task has been scheduled to acquire the lock next
13+
self.state = 0
14+
# Queue of Tasks waiting to acquire this Lock
15+
self.waiting = core.TaskQueue()
1116

1217
def locked(self):
13-
return self.state == 2
18+
return self.state == 1
1419

1520
def release(self):
16-
if self.state != 2:
21+
if self.state != 1:
1722
raise RuntimeError
1823
if self.waiting.peek():
19-
# Task(s) waiting on lock, schedule first Task
20-
core._task_queue.push_head(self.waiting.pop_head())
21-
self.state = 1
24+
# Task(s) waiting on lock, schedule next Task
25+
self.state = self.waiting.pop_head()
26+
core._task_queue.push_head(self.state)
2227
else:
2328
# No Task waiting so unlock
2429
self.state = 0
2530

2631
async def acquire(self):
27-
if self.state != 0 or self.waiting.peek():
32+
if self.state != 0:
2833
# Lock unavailable, put the calling Task on the waiting queue
2934
self.waiting.push_head(core.cur_task)
3035
# Set calling task's data to the lock's queue so it can be removed if needed
3136
core.cur_task.data = self.waiting
3237
try:
3338
yield
3439
except core.CancelledError as er:
35-
if self.state == 1:
40+
if self.state == core.cur_task:
3641
# Cancelled while pending on resume, schedule next waiting Task
37-
self.state = 2
42+
self.state = 1
3843
self.release()
3944
raise er
4045
# Lock available, set it as locked
41-
self.state = 2
46+
self.state = 1
4247
return True
4348

4449
async def __aenter__(self):

0 commit comments

Comments
 (0)
0