Skip to content

Commit bbce744

Browse files
Merge branch 'asyncio-docs' of https://github.com/kumaraditya303/cpython into asyncio-docs
2 parents 5c25673 + 32f36e2 commit bbce744

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

InternalDocs/asyncio.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ This document describes the working and implementation details of C implementati
1010

1111
Until Python 3.13, the C implementation of `asyncio` used a [`WeakSet`](https://docs.python.org/3/library/weakref.html#weakref.WeakSet) to store all the tasks created by the event loop. `WeakSet` was used so that the event loop
1212
doesn't hold strong references to the tasks, allowing them to be garbage collected when they are no longer needed.
13-
The current task of the event loop was stored in dict mapping the event loop to the current task.
13+
The current task of the event loop was stored in a dict mapping the event loop to the current task.
1414

1515
```c
1616
/* Dictionary containing tasks that are currently active in
@@ -44,7 +44,7 @@ This implementation uses a circular doubly linked list to store tasks on the thr
4444

4545
The `PyThreadState` structure gained a new field `asyncio_tasks_head`, which serves as the head of the circular linked list of tasks. This allows for lock free addition and removal of tasks from the list.
4646

47-
It is possible that when a thread state is deallocated, there are lingering tasks in it's list, this can happen if another thread has references to the tasks of this thread as such the `PyInterpreterState` structure also gains a new `asyncio_tasks_head` field to store any lingering tasks. When a thread state is deallocated, any remaining lingering tasks are moved to the interpreter state tasks list, and the thread state tasks list is cleared.
47+
It is possible that when a thread state is deallocated, there are lingering tasks in its list; this can happen if another thread has references to the tasks of this thread. Therefore, the `PyInterpreterState` structure also gains a new `asyncio_tasks_head` field to store any lingering tasks. When a thread state is deallocated, any remaining lingering tasks are moved to the interpreter state tasks list, and the thread state tasks list is cleared.
4848
The `asyncio_tasks_lock` is used protect the interpreter's tasks list from concurrent modifications.
4949

5050

@@ -66,27 +66,27 @@ typedef struct PyInterpreterState {
6666
} PyInterpreterState;
6767
```
6868

69-
When a task is created, it is added to the current thread's list of tasks by the `register_task` function. When the task is done, it is removed from the list by the `unregister_task` function. In free-threading, the thread id of thread which
69+
When a task is created, it is added to the current thread's list of tasks by the `register_task` function. When the task is done, it is removed from the list by the `unregister_task` function. In free-threading, the thread id of the thread which
7070
created the task is stored in `task_tid` field of the `TaskObj`. This is used to check if the task is being removed from the correct thread's task list. If the current thread is same as the thread which created it then no locking is required, otherwise in free-threading, the `stop-the-world` pause is used to pause all other threads and then safely remove the task from the tasks list.
7171

7272
```mermaid
7373
flowchart TD
7474
subgraph one["Executing Thread"]
7575
A["task = asyncio.create_task(coro())"] -->B("register_task(task)")
76-
B --> C{"task->task_state"}
76+
B --> C{"task->task_state?"}
7777
C -->|pending| D["task_step(task)"]
7878
C -->|done| F["unregister_task(task)"]
7979
C -->|cancelled| F["unregister_task(task)"]
8080
D --> C
81-
F --> G{"free-threading"}
81+
F --> G{"free-threading?"}
8282
G --> |false| H["unregister_task_safe(task)"]
83-
G --> |true| J{"check correct thread <br>task->task_tid == _Py_ThreadId()"}
83+
G --> |true| J{"correct thread? <br>task->task_tid == _Py_ThreadId()"}
8484
J --> |true| H
8585
J --> |false| I["stop the world <br> pause all threads"]
8686
I --> H["unregister_task_safe(task)"]
8787
end
8888
subgraph two["Thread deallocating"]
89-
A1{"check thread's task list is empty <br> llist_empty(tstate->asyncio_tasks_head)"}
89+
A1{"thread's task list empty? <br> llist_empty(tstate->asyncio_tasks_head)"}```
9090
A1 --> |true| B1["deallocate thread<br>free_threadstate(tstate)"]
9191
A1 --> |false| C1["add tasks to interpreter's task list<br> llist_concat(&tstate->interp->asyncio_tasks_head,tstate->asyncio_tasks_head)"]
9292
C1 --> B1

0 commit comments

Comments
 (0)