Skip to content

Commit 441adb8

Browse files
committed
Backout changeset 46393019b650
test_capi is failing and the fix is not trivial, I prefer to revert
1 parent 775632b commit 441adb8

File tree

7 files changed

+30
-24
lines changed

7 files changed

+30
-24
lines changed

Doc/whatsnew/3.4.rst

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,8 +1068,3 @@ that may require changes to your code.
10681068
working directory will also now have an absolute path, including when using
10691069
``-m`` with the interpreter (this does not influence when the path to a file
10701070
is specified on the command-line).
1071-
1072-
* (C API) :c:func:`PyThread_set_key_value` now always set the value. In Python
1073-
3.3, the function did nothing if the key already exists (if the current
1074-
value is a non-NULL pointer).
1075-

Misc/NEWS

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@ Release date: 2014-01-05
1010
Core and Builtins
1111
-----------------
1212

13-
- Issue #19787: PyThread_set_key_value() now always set the value. In Python
14-
3.3, the function did nothing if the key already exists (if the current value
15-
is a non-NULL pointer).
16-
1713
- Issue #14432: Remove the thread state field from the frame structure. Fix a
1814
crash when a generator is created in a C thread that is destroyed while the
1915
generator is still used. The issue was that a generator contains a frame, and

Modules/_testcapimodule.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2511,10 +2511,6 @@ run_in_subinterp(PyObject *self, PyObject *args)
25112511
r = PyRun_SimpleString(code);
25122512
Py_EndInterpreter(substate);
25132513

2514-
/* restore previous thread safe. It was replaced by Py_NewInterpreter()
2515-
which creates a new thread state. */
2516-
_PyThreadState_Init(mainstate);
2517-
25182514
PyThreadState_Swap(mainstate);
25192515

25202516
return PyLong_FromLong(r);

Modules/_tracemalloc.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,14 @@ set_reentrant(int reentrant)
168168
assert(reentrant == 0 || reentrant == 1);
169169
if (reentrant) {
170170
assert(PyThread_get_key_value(tracemalloc_reentrant_key) == NULL);
171-
PyThread_set_key_value(tracemalloc_reentrant_key, REENTRANT);
171+
PyThread_set_key_value(tracemalloc_reentrant_key,
172+
REENTRANT);
172173
}
173174
else {
174-
assert(PyThread_get_key_value(tracemalloc_reentrant_key) == REENTRANT);
175-
PyThread_set_key_value(tracemalloc_reentrant_key, NULL);
175+
/* FIXME: PyThread_set_key_value() cannot be used to set the flag
176+
to zero, because it does nothing if the variable has already
177+
a value set. */
178+
PyThread_delete_key_value(tracemalloc_reentrant_key);
176179
}
177180
}
178181

Python/thread.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ static int nkeys = 0; /* PyThread_create_key() hands out nkeys+1 next */
205205
* segfaults. Now we lock the whole routine.
206206
*/
207207
static struct key *
208-
find_key(int key, int update, void *value)
208+
find_key(int key, void *value)
209209
{
210210
struct key *p, *prev_p;
211211
long id = PyThread_get_thread_ident();
@@ -215,11 +215,8 @@ find_key(int key, int update, void *value)
215215
PyThread_acquire_lock(keymutex, 1);
216216
prev_p = NULL;
217217
for (p = keyhead; p != NULL; p = p->next) {
218-
if (p->id == id && p->key == key) {
219-
if (update)
220-
p->value = value;
218+
if (p->id == id && p->key == key)
221219
goto Done;
222-
}
223220
/* Sanity check. These states should never happen but if
224221
* they do we must abort. Otherwise we'll end up spinning in
225222
* in a tight loop with the lock held. A similar check is done
@@ -230,7 +227,7 @@ find_key(int key, int update, void *value)
230227
if (p->next == keyhead)
231228
Py_FatalError("tls find_key: circular list(!)");
232229
}
233-
if (!update && value == NULL) {
230+
if (value == NULL) {
234231
assert(p == NULL);
235232
goto Done;
236233
}
@@ -282,12 +279,19 @@ PyThread_delete_key(int key)
282279
PyThread_release_lock(keymutex);
283280
}
284281

282+
/* Confusing: If the current thread has an association for key,
283+
* value is ignored, and 0 is returned. Else an attempt is made to create
284+
* an association of key to value for the current thread. 0 is returned
285+
* if that succeeds, but -1 is returned if there's not enough memory
286+
* to create the association. value must not be NULL.
287+
*/
285288
int
286289
PyThread_set_key_value(int key, void *value)
287290
{
288291
struct key *p;
289292

290-
p = find_key(key, 1, value);
293+
assert(value != NULL);
294+
p = find_key(key, value);
291295
if (p == NULL)
292296
return -1;
293297
else
@@ -300,7 +304,7 @@ PyThread_set_key_value(int key, void *value)
300304
void *
301305
PyThread_get_key_value(int key)
302306
{
303-
struct key *p = find_key(key, 0, NULL);
307+
struct key *p = find_key(key, NULL);
304308

305309
if (p == NULL)
306310
return NULL;

Python/thread_nt.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,11 +389,20 @@ PyThread_delete_key(int key)
389389
TlsFree(key);
390390
}
391391

392+
/* We must be careful to emulate the strange semantics implemented in thread.c,
393+
* where the value is only set if it hasn't been set before.
394+
*/
392395
int
393396
PyThread_set_key_value(int key, void *value)
394397
{
395398
BOOL ok;
399+
void *oldvalue;
396400

401+
assert(value != NULL);
402+
oldvalue = TlsGetValue(key);
403+
if (oldvalue != NULL)
404+
/* ignore value if already set */
405+
return 0;
397406
ok = TlsSetValue(key, value);
398407
if (!ok)
399408
return -1;

Python/thread_pthread.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,9 @@ int
627627
PyThread_set_key_value(int key, void *value)
628628
{
629629
int fail;
630+
void *oldValue = pthread_getspecific(key);
631+
if (oldValue != NULL)
632+
return 0;
630633
fail = pthread_setspecific(key, value);
631634
return fail ? -1 : 0;
632635
}

0 commit comments

Comments
 (0)