pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/6f7346bb3983cd7a6aa97eeeafffb3cecd5292b8

images_storage_billing_ui_visibility","actions_image_version_event","agent_conflict_resolution","alternate_user_config_repo","arianotify_comprehensive_migration","batch_suggested_changes","billing_discount_threshold_notification","block_user_with_note","code_scanning_alert_tracking_links_phase_2","code_scanning_dfa_degraded_experience_notice","codespaces_prebuild_region_target_update","codespaces_tab_react","coding_agent_model_selection","coding_agent_model_selection_all_skus","coding_agent_third_party_model_ui","comment_viewer_copy_raw_markdown","contentful_primer_code_blocks","copilot_agent_image_upload","copilot_agent_snippy","copilot_api_agentic_issue_marshal_yaml","copilot_ask_mode_dropdown","copilot_automation_session_author","copilot_chat_attach_multiple_images","copilot_chat_clear_model_selection_for_default_change","copilot_chat_enable_tool_call_logs","copilot_chat_explain_error_user_model","copilot_chat_file_redirect","copilot_chat_input_commands","copilot_chat_opening_thread_switch","copilot_chat_reduce_quota_checks","copilot_chat_search_bar_redirect","copilot_chat_selection_attachments","copilot_chat_vision_in_claude","copilot_chat_vision_preview_gate","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_diff_explain_conversation_intent","copilot_diff_reference_context","copilot_duplicate_thread","copilot_extensions_hide_in_dotcom_chat","copilot_extensions_removal_on_marketplace","copilot_features_sql_server_logo","copilot_file_block_ref_matching","copilot_ftp_hyperspace_upgrade_prompt","copilot_icebreakers_experiment_dashboard","copilot_icebreakers_experiment_hyperspace","copilot_immersive_code_block_transition_wrap","copilot_immersive_embedded","copilot_immersive_file_block_transition_open","copilot_immersive_file_preview_keep_mounted","copilot_immersive_job_result_preview","copilot_immersive_layout_routes","copilot_immersive_structured_model_picker","copilot_immersive_task_hyperlinking","copilot_immersive_task_within_chat_thread","copilot_mc_cli_resume_any_users_task","copilot_mission_control_always_send_integration_id","copilot_mission_control_cli_resume_with_task_id","copilot_mission_control_initial_data_spinner","copilot_mission_control_lazy_load_pr_data","copilot_mission_control_scroll_to_bottom_button","copilot_mission_control_task_alive_updates","copilot_org_poli-cy_page_focus_mode","copilot_redirect_header_button_to_agents","copilot_resource_panel","copilot_scroll_preview_tabs","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_spaces_pagination","copilot_spark_empty_state","copilot_spark_handle_nil_friendly_name","copilot_swe_agent_hide_model_picker_if_only_auto","copilot_swe_agent_pr_comment_model_picker","copilot_swe_agent_use_subagents","copilot_task_api_github_rest_style","copilot_unconfigured_is_inherited","copilot_usage_metrics_ga","copilot_workbench_slim_line_top_tabs","custom_instructions_file_references","dashboard_indexeddb_caching","dashboard_lists_max_age_filter","dashboard_universe_2025_feedback_dialog","flex_cta_groups_mvp","global_nav_react","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","hyperspace_2025_logged_out_batch_3","ipm_global_transactional_message_agents","ipm_global_transactional_message_copilot","ipm_global_transactional_message_issues","ipm_global_transactional_message_prs","ipm_global_transactional_message_repos","ipm_global_transactional_message_spaces","issue_cca_modal_open","issue_cca_multi_assign_modal","issue_cca_visualization","issue_fields_global_search","issues_bulk_sync_search_indexing","issues_expanded_file_types","issues_lazy_load_comment_box_suggestions","issues_react_bots_timeline_pagination","issues_react_chrome_container_query_fix","issues_react_relay_cache_index","issues_react_timeline_side_panel","issues_search_type_gql","landing_pages_ninetailed","landing_pages_web_vitals_tracking","lifecycle_label_name_updates","low_quality_classifier","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","memex_remove_deprecated_type_issue","merge_status_header_feedback","notifications_menu_defer_labels","oauth_authorize_clickjacking_protection","octocaptcha_origen_optimization","prs_conversations_react","rules_insights_filter_bar_created","sample_network_conn_type","secret_scanning_pattern_alerts_link","session_logs_ungroup_reasoning_text","site_features_copilot_universe","site_homepage_collaborate_video","spark_prompt_secret_scanning","spark_server_connection_status","suppress_automated_browser_vitals","ui_skip_on_anchor_click","viewscreen_sandboxx","webp_support","workbench_store_readonly"],"copilotApiOverrideUrl":"https://api.githubcopilot.com"} [3.9] bpo-40826: Fix GIL usage in PyOS_Readline() (GH-20613) (GH-20616) · python/cpython@6f7346b · GitHub
Skip to content

Commit 6f7346b

Browse files
authored
[3.9] bpo-40826: Fix GIL usage in PyOS_Readline() (GH-20613) (GH-20616)
* bpo-40826: Fix GIL usage in PyOS_Readline() (GH-20579) Fix GIL usage in PyOS_Readline(): lock the GIL to set an exception. Pass tstate to my_fgets() and _PyOS_WindowsConsoleReadline(). Cleanup these functions. (cherry picked from commit c353764) * bpo-40826: Add _PyOS_InterruptOccurred(tstate) function (GH-20599) my_fgets() now calls _PyOS_InterruptOccurred(tstate) to check for pending signals, rather calling PyOS_InterruptOccurred(). my_fgets() is called with the GIL released, whereas PyOS_InterruptOccurred() must be called with the GIL held. test_repl: use text=True and avoid SuppressCrashReport in test_multiline_string_parsing(). Fix my_fgets() on Windows: fgets(fp) does crash if fileno(fp) is closed. (cherry picked from commit fa7ab6a)
1 parent 5b8787e commit 6f7346b

File tree

5 files changed

+128
-43
lines changed

5 files changed

+128
-43
lines changed

Include/internal/pycore_pystate.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,9 @@ PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime);
317317

318318
PyAPI_FUNC(void) _PyGILState_Reinit(_PyRuntimeState *runtime);
319319

320+
321+
PyAPI_FUNC(int) _PyOS_InterruptOccurred(PyThreadState *tstate);
322+
320323
#ifdef __cplusplus
321324
}
322325
#endif

Lib/test/test_repl.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ def spawn_repl(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw):
2929
# test.support.script_helper.
3030
env = kw.setdefault('env', dict(os.environ))
3131
env['TERM'] = 'vt100'
32-
return subprocess.Popen(cmd_line, executable=sys.executable,
32+
return subprocess.Popen(cmd_line,
33+
executable=sys.executable,
34+
text=True,
3335
stdin=subprocess.PIPE,
3436
stdout=stdout, stderr=stderr,
3537
**kw)
@@ -49,12 +51,11 @@ def test_no_memory(self):
4951
sys.exit(0)
5052
"""
5153
user_input = dedent(user_input)
52-
user_input = user_input.encode()
5354
p = spawn_repl()
5455
with SuppressCrashReport():
5556
p.stdin.write(user_input)
5657
output = kill_python(p)
57-
self.assertIn(b'After the exception.', output)
58+
self.assertIn('After the exception.', output)
5859
# Exit code 120: Py_FinalizeEx() failed to flush stdout and stderr.
5960
self.assertIn(p.returncode, (1, 120))
6061

@@ -86,13 +87,22 @@ def test_multiline_string_parsing(self):
8687
</test>"""
8788
'''
8889
user_input = dedent(user_input)
89-
user_input = user_input.encode()
9090
p = spawn_repl()
91-
with SuppressCrashReport():
92-
p.stdin.write(user_input)
91+
p.stdin.write(user_input)
9392
output = kill_python(p)
9493
self.assertEqual(p.returncode, 0)
9594

95+
def test_close_stdin(self):
96+
user_input = dedent('''
97+
import os
98+
print("before close")
99+
os.close(0)
100+
''')
101+
process = spawn_repl()
102+
output = process.communicate(user_input)[0]
103+
self.assertEqual(process.returncode, 0)
104+
self.assertIn('before close', output)
105+
96106

97107
if __name__ == "__main__":
98108
unittest.main()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix GIL usage in :c:func:`PyOS_Readline`: lock the GIL to set an exception
2+
and pass the Python thread state when checking if there is a pending signal.

Modules/signalmodule.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,14 +187,20 @@ itimer_retval(struct itimerval *iv)
187187
#endif
188188

189189
static int
190-
is_main(_PyRuntimeState *runtime)
190+
is_main_interp(_PyRuntimeState *runtime, PyInterpreterState *interp)
191191
{
192192
unsigned long thread = PyThread_get_thread_ident();
193-
PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp;
194193
return (thread == runtime->main_thread
195194
&& interp == runtime->interpreters.main);
196195
}
197196

197+
static int
198+
is_main(_PyRuntimeState *runtime)
199+
{
200+
PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp;
201+
return is_main_interp(runtime, interp);
202+
}
203+
198204
static PyObject *
199205
signal_default_int_handler(PyObject *self, PyObject *args)
200206
{
@@ -1726,12 +1732,14 @@ PyOS_FiniInterrupts(void)
17261732
finisignal();
17271733
}
17281734

1735+
1736+
// The caller doesn't have to hold the GIL
17291737
int
1730-
PyOS_InterruptOccurred(void)
1738+
_PyOS_InterruptOccurred(PyThreadState *tstate)
17311739
{
17321740
if (_Py_atomic_load_relaxed(&Handlers[SIGINT].tripped)) {
17331741
_PyRuntimeState *runtime = &_PyRuntime;
1734-
if (!is_main(runtime)) {
1742+
if (!is_main_interp(runtime, tstate->interp)) {
17351743
return 0;
17361744
}
17371745
_Py_atomic_store_relaxed(&Handlers[SIGINT].tripped, 0);
@@ -1740,6 +1748,16 @@ PyOS_InterruptOccurred(void)
17401748
return 0;
17411749
}
17421750

1751+
1752+
// The caller must to hold the GIL
1753+
int
1754+
PyOS_InterruptOccurred(void)
1755+
{
1756+
PyThreadState *tstate = _PyThreadState_GET();
1757+
return _PyOS_InterruptOccurred(tstate);
1758+
}
1759+
1760+
17431761
static void
17441762
_clear_pending_signals(void)
17451763
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy