Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
e377416c
Kaydet (Commit)
e377416c
authored
May 23, 2017
tarafından
Eric Snow
Kaydeden (comit)
GitHub
May 23, 2017
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
bpo-29102: Add a unique ID to PyInterpreterState. (#1639)
üst
93fc20b7
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
152 additions
and
7 deletions
+152
-7
init.rst
Doc/c-api/init.rst
+8
-0
pystate.h
Include/pystate.h
+9
-0
test_capi.py
Lib/test/test_capi.py
+86
-5
NEWS
Misc/NEWS
+3
-0
python3.def
PC/python3.def
+1
-0
_testembed.c
Programs/_testembed.c
+7
-2
pylifecycle.c
Python/pylifecycle.c
+1
-0
pystate.c
Python/pystate.c
+37
-0
No files found.
Doc/c-api/init.rst
Dosyayı görüntüle @
e377416c
...
...
@@ -821,6 +821,14 @@ been created.
:c:func:`PyThreadState_Clear`.
.. c:function:: PY_INT64_T PyInterpreterState_GetID(PyInterpreterState *interp)
Return the interpreter's unique ID. If there was any error in doing
so then -1 is returned and an error is set.
.. versionadded:: 3.7
.. c:function:: PyObject* PyThreadState_GetDict()
Return a dictionary in which extensions can store thread-specific state
...
...
Include/pystate.h
Dosyayı görüntüle @
e377416c
...
...
@@ -28,6 +28,8 @@ typedef struct _is {
struct
_is
*
next
;
struct
_ts
*
tstate_head
;
int64_t
id
;
PyObject
*
modules
;
PyObject
*
modules_by_index
;
PyObject
*
sysdict
;
...
...
@@ -154,9 +156,16 @@ typedef struct _ts {
#endif
#ifndef Py_LIMITED_API
PyAPI_FUNC
(
void
)
_PyInterpreterState_Init
(
void
);
#endif
/* !Py_LIMITED_API */
PyAPI_FUNC
(
PyInterpreterState
*
)
PyInterpreterState_New
(
void
);
PyAPI_FUNC
(
void
)
PyInterpreterState_Clear
(
PyInterpreterState
*
);
PyAPI_FUNC
(
void
)
PyInterpreterState_Delete
(
PyInterpreterState
*
);
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000
/* New in 3.7 */
PyAPI_FUNC
(
int64_t
)
PyInterpreterState_GetID
(
PyInterpreterState
*
);
#endif
#ifndef Py_LIMITED_API
PyAPI_FUNC
(
int
)
_PyState_AddModule
(
PyObject
*
,
struct
PyModuleDef
*
);
#endif
/* !Py_LIMITED_API */
...
...
Lib/test/test_capi.py
Dosyayı görüntüle @
e377416c
# Run the _testcapi module tests (tests for the Python/C API): by defn,
# these are all functions _testcapi exports whose name begins with 'test_'.
from
collections
import
namedtuple
import
os
import
pickle
import
platform
import
random
import
re
import
subprocess
...
...
@@ -384,12 +386,91 @@ class EmbeddingTests(unittest.TestCase):
return
out
,
err
def
test_subinterps
(
self
):
# This is just a "don't crash" test
out
,
err
=
self
.
run_embedded_interpreter
(
"repeated_init_and_subinterpreters"
)
if
support
.
verbose
:
print
()
print
(
out
)
print
(
err
)
self
.
assertEqual
(
err
,
""
)
# The output from _testembed looks like this:
# --- Pass 0 ---
# interp 0 <0x1cf9330>, thread state <0x1cf9700>: id(modules) = 139650431942728
# interp 1 <0x1d4f690>, thread state <0x1d35350>: id(modules) = 139650431165784
# interp 2 <0x1d5a690>, thread state <0x1d99ed0>: id(modules) = 139650413140368
# interp 3 <0x1d4f690>, thread state <0x1dc3340>: id(modules) = 139650412862200
# interp 0 <0x1cf9330>, thread state <0x1cf9700>: id(modules) = 139650431942728
# --- Pass 1 ---
# ...
interp_pat
=
(
r"^interp (\d+) <(0x[\dA-F]+)>, "
r"thread state <(0x[\dA-F]+)>: "
r"id\(modules\) = ([\d]+)$"
)
Interp
=
namedtuple
(
"Interp"
,
"id interp tstate modules"
)
main
=
None
lastmain
=
None
numinner
=
None
numloops
=
0
for
line
in
out
.
splitlines
():
if
line
==
"--- Pass {} ---"
.
format
(
numloops
):
if
numinner
is
not
None
:
self
.
assertEqual
(
numinner
,
5
)
if
support
.
verbose
:
print
(
line
)
lastmain
=
main
main
=
None
mainid
=
0
numloops
+=
1
numinner
=
0
continue
numinner
+=
1
self
.
assertLessEqual
(
numinner
,
5
)
match
=
re
.
match
(
interp_pat
,
line
)
if
match
is
None
:
self
.
assertRegex
(
line
,
interp_pat
)
# The last line in the loop should be the same as the first.
if
numinner
==
5
:
self
.
assertEqual
(
match
.
groups
(),
main
)
continue
# Parse the line from the loop. The first line is the main
# interpreter and the 3 afterward are subinterpreters.
interp
=
Interp
(
*
match
.
groups
())
if
support
.
verbose
:
print
(
interp
)
if
numinner
==
1
:
main
=
interp
id
=
str
(
mainid
)
else
:
subid
=
mainid
+
numinner
-
1
id
=
str
(
subid
)
# Validate the loop line for each interpreter.
self
.
assertEqual
(
interp
.
id
,
id
)
self
.
assertTrue
(
interp
.
interp
)
self
.
assertTrue
(
interp
.
tstate
)
self
.
assertTrue
(
interp
.
modules
)
if
platform
.
system
()
==
'Windows'
:
# XXX Fix on Windows: something is going on with the
# pointers in Programs/_testembed.c. interp.interp
# is 0x0 and # interp.modules is the same between
# interpreters.
continue
if
interp
is
main
:
if
lastmain
is
not
None
:
# A new main interpreter may have the same interp
# and/or tstate pointer as an earlier finalized/
# destroyed one. So we do not check interp or
# tstate here.
self
.
assertNotEqual
(
interp
.
modules
,
lastmain
.
modules
)
else
:
# A new subinterpreter may have the same
# PyInterpreterState pointer as a previous one if
# the earlier one has already been destroyed. So
# we compare with the main interpreter. The same
# applies to tstate.
self
.
assertNotEqual
(
interp
.
interp
,
main
.
interp
)
self
.
assertNotEqual
(
interp
.
tstate
,
main
.
tstate
)
self
.
assertNotEqual
(
interp
.
modules
,
main
.
modules
)
@staticmethod
def
_get_default_pipe_encoding
():
...
...
Misc/NEWS
Dosyayı görüntüle @
e377416c
...
...
@@ -53,6 +53,9 @@ Core and Builtins
-
bpo
-
24821
:
Fixed
the
slowing
down
to
25
times
in
the
searching
of
some
unlucky
Unicode
characters
.
-
bpo
-
29102
:
Add
a
unique
ID
to
PyInterpreterState
.
This
makes
it
easier
to
identify
each
subinterpreter
.
-
bpo
-
29894
:
The
deprecation
warning
is
emitted
if
__complex__
returns
an
instance
of
a
strict
subclass
of
complex
.
In
a
future
versions
of
Python
this
can
be
an
error
.
...
...
PC/python3.def
Dosyayı görüntüle @
e377416c
...
...
@@ -538,6 +538,7 @@ EXPORTS
PySlice_Type=python37.PySlice_Type DATA
PySlice_Unpack=python37.PySlice_Unpack
PySortWrapper_Type=python37.PySortWrapper_Type DATA
PyInterpreterState_GetID=python37.PyInterpreterState_GetID
PyState_AddModule=python37.PyState_AddModule
PyState_FindModule=python37.PyState_FindModule
PyState_RemoveModule=python37.PyState_RemoveModule
...
...
Programs/_testembed.c
Dosyayı görüntüle @
e377416c
#include <Python.h>
#include <inttypes.h>
#include <stdio.h>
/*********************************************************
...
...
@@ -22,9 +23,13 @@ static void _testembed_Py_Initialize(void)
static
void
print_subinterp
(
void
)
{
/* Just output some debug stuff */
/* Output information about the interpreter in the format
expected in Lib/test/test_capi.py (test_subinterps). */
PyThreadState
*
ts
=
PyThreadState_Get
();
printf
(
"interp %p, thread state %p: "
,
ts
->
interp
,
ts
);
PyInterpreterState
*
interp
=
ts
->
interp
;
int64_t
id
=
PyInterpreterState_GetID
(
interp
);
printf
(
"interp %lu <0x%"
PRIXPTR
">, thread state <0x%"
PRIXPTR
">: "
,
id
,
(
uintptr_t
)
interp
,
(
uintptr_t
)
ts
);
fflush
(
stdout
);
PyRun_SimpleString
(
"import sys;"
...
...
Python/pylifecycle.c
Dosyayı görüntüle @
e377416c
...
...
@@ -344,6 +344,7 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
_PyRandom_Init
();
_PyInterpreterState_Init
();
interp
=
PyInterpreterState_New
();
if
(
interp
==
NULL
)
Py_FatalError
(
"Py_Initialize: can't make first interpreter"
);
...
...
Python/pystate.c
Dosyayı görüntüle @
e377416c
...
...
@@ -65,6 +65,23 @@ PyThreadFrameGetter _PyThreadState_GetFrame = NULL;
static
void
_PyGILState_NoteThreadState
(
PyThreadState
*
tstate
);
#endif
/* _next_interp_id is an auto-numbered sequence of small integers.
It gets initialized in _PyInterpreterState_Init(), which is called
in Py_Initialize(), and used in PyInterpreterState_New(). A negative
interpreter ID indicates an error occurred. The main interpreter
will always have an ID of 0. Overflow results in a RuntimeError.
If that becomes a problem later then we can adjust, e.g. by using
a Python int.
We initialize this to -1 so that the pre-Py_Initialize() value
results in an error. */
static
int64_t
_next_interp_id
=
-
1
;
void
_PyInterpreterState_Init
(
void
)
{
_next_interp_id
=
0
;
}
PyInterpreterState
*
PyInterpreterState_New
(
void
)
...
...
@@ -103,6 +120,15 @@ PyInterpreterState_New(void)
HEAD_LOCK
();
interp
->
next
=
interp_head
;
interp_head
=
interp
;
if
(
_next_interp_id
<
0
)
{
/* overflow or Py_Initialize() not called! */
PyErr_SetString
(
PyExc_RuntimeError
,
"failed to get an interpreter ID"
);
interp
=
NULL
;
}
else
{
interp
->
id
=
_next_interp_id
;
_next_interp_id
+=
1
;
}
HEAD_UNLOCK
();
}
...
...
@@ -170,6 +196,17 @@ PyInterpreterState_Delete(PyInterpreterState *interp)
}
int64_t
PyInterpreterState_GetID
(
PyInterpreterState
*
interp
)
{
if
(
interp
==
NULL
)
{
PyErr_SetString
(
PyExc_RuntimeError
,
"no interpreter provided"
);
return
-
1
;
}
return
interp
->
id
;
}
/* Default implementation for _PyThreadState_GetFrame */
static
struct
_frame
*
threadstate_getframe
(
PyThreadState
*
self
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment