mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	Backout changeset 46393019b650
test_capi is failing and the fix is not trivial, I prefer to revert
This commit is contained in:
		
							parent
							
								
									775632ba10
								
							
						
					
					
						commit
						441adb8c57
					
				
					 7 changed files with 30 additions and 24 deletions
				
			
		|  | @ -1068,8 +1068,3 @@ that may require changes to your code. | ||||||
|   working directory will also now have an absolute path, including when using |   working directory will also now have an absolute path, including when using | ||||||
|   ``-m`` with the interpreter (this does not influence when the path to a file |   ``-m`` with the interpreter (this does not influence when the path to a file | ||||||
|   is specified on the command-line). |   is specified on the command-line). | ||||||
| 
 |  | ||||||
| * (C API) :c:func:`PyThread_set_key_value` now always set the value. In Python |  | ||||||
|   3.3, the function did nothing if the key already exists (if the current |  | ||||||
|   value is a non-NULL pointer). |  | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -10,10 +10,6 @@ Release date: 2014-01-05 | ||||||
| Core and Builtins | Core and Builtins | ||||||
| ----------------- | ----------------- | ||||||
| 
 | 
 | ||||||
| - Issue #19787: PyThread_set_key_value() now always set the value. In Python |  | ||||||
|   3.3, the function did nothing if the key already exists (if the current value |  | ||||||
|   is a non-NULL pointer). |  | ||||||
| 
 |  | ||||||
| - Issue #14432: Remove the thread state field from the frame structure. Fix a | - Issue #14432: Remove the thread state field from the frame structure. Fix a | ||||||
|   crash when a generator is created in a C thread that is destroyed while the |   crash when a generator is created in a C thread that is destroyed while the | ||||||
|   generator is still used. The issue was that a generator contains a frame, and |   generator is still used. The issue was that a generator contains a frame, and | ||||||
|  |  | ||||||
|  | @ -2511,10 +2511,6 @@ run_in_subinterp(PyObject *self, PyObject *args) | ||||||
|     r = PyRun_SimpleString(code); |     r = PyRun_SimpleString(code); | ||||||
|     Py_EndInterpreter(substate); |     Py_EndInterpreter(substate); | ||||||
| 
 | 
 | ||||||
|     /* restore previous thread safe. It was replaced by Py_NewInterpreter()
 |  | ||||||
|        which creates a new thread state. */ |  | ||||||
|     _PyThreadState_Init(mainstate); |  | ||||||
| 
 |  | ||||||
|     PyThreadState_Swap(mainstate); |     PyThreadState_Swap(mainstate); | ||||||
| 
 | 
 | ||||||
|     return PyLong_FromLong(r); |     return PyLong_FromLong(r); | ||||||
|  |  | ||||||
|  | @ -168,11 +168,14 @@ set_reentrant(int reentrant) | ||||||
|     assert(reentrant == 0 || reentrant == 1); |     assert(reentrant == 0 || reentrant == 1); | ||||||
|     if (reentrant) { |     if (reentrant) { | ||||||
|         assert(PyThread_get_key_value(tracemalloc_reentrant_key) == NULL); |         assert(PyThread_get_key_value(tracemalloc_reentrant_key) == NULL); | ||||||
|         PyThread_set_key_value(tracemalloc_reentrant_key, REENTRANT); |         PyThread_set_key_value(tracemalloc_reentrant_key, | ||||||
|  |                                REENTRANT); | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|         assert(PyThread_get_key_value(tracemalloc_reentrant_key) == REENTRANT); |         /* FIXME: PyThread_set_key_value() cannot be used to set the flag
 | ||||||
|         PyThread_set_key_value(tracemalloc_reentrant_key, NULL); |            to zero, because it does nothing if the variable has already | ||||||
|  |            a value set. */ | ||||||
|  |         PyThread_delete_key_value(tracemalloc_reentrant_key); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -205,7 +205,7 @@ static int nkeys = 0;  /* PyThread_create_key() hands out nkeys+1 next */ | ||||||
|  * segfaults.  Now we lock the whole routine. |  * segfaults.  Now we lock the whole routine. | ||||||
|  */ |  */ | ||||||
| static struct key * | static struct key * | ||||||
| find_key(int key, int update, void *value) | find_key(int key, void *value) | ||||||
| { | { | ||||||
|     struct key *p, *prev_p; |     struct key *p, *prev_p; | ||||||
|     long id = PyThread_get_thread_ident(); |     long id = PyThread_get_thread_ident(); | ||||||
|  | @ -215,11 +215,8 @@ find_key(int key, int update, void *value) | ||||||
|     PyThread_acquire_lock(keymutex, 1); |     PyThread_acquire_lock(keymutex, 1); | ||||||
|     prev_p = NULL; |     prev_p = NULL; | ||||||
|     for (p = keyhead; p != NULL; p = p->next) { |     for (p = keyhead; p != NULL; p = p->next) { | ||||||
|         if (p->id == id && p->key == key) { |         if (p->id == id && p->key == key) | ||||||
|             if (update) |  | ||||||
|                 p->value = value; |  | ||||||
|             goto Done; |             goto Done; | ||||||
|         } |  | ||||||
|         /* Sanity check.  These states should never happen but if
 |         /* Sanity check.  These states should never happen but if
 | ||||||
|          * they do we must abort.  Otherwise we'll end up spinning in |          * they do we must abort.  Otherwise we'll end up spinning in | ||||||
|          * in a tight loop with the lock held.  A similar check is done |          * 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) | ||||||
|         if (p->next == keyhead) |         if (p->next == keyhead) | ||||||
|             Py_FatalError("tls find_key: circular list(!)"); |             Py_FatalError("tls find_key: circular list(!)"); | ||||||
|     } |     } | ||||||
|     if (!update && value == NULL) { |     if (value == NULL) { | ||||||
|         assert(p == NULL); |         assert(p == NULL); | ||||||
|         goto Done; |         goto Done; | ||||||
|     } |     } | ||||||
|  | @ -282,12 +279,19 @@ PyThread_delete_key(int key) | ||||||
|     PyThread_release_lock(keymutex); |     PyThread_release_lock(keymutex); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* Confusing:  If the current thread has an association for key,
 | ||||||
|  |  * value is ignored, and 0 is returned.  Else an attempt is made to create | ||||||
|  |  * an association of key to value for the current thread.  0 is returned | ||||||
|  |  * if that succeeds, but -1 is returned if there's not enough memory | ||||||
|  |  * to create the association.  value must not be NULL. | ||||||
|  |  */ | ||||||
| int | int | ||||||
| PyThread_set_key_value(int key, void *value) | PyThread_set_key_value(int key, void *value) | ||||||
| { | { | ||||||
|     struct key *p; |     struct key *p; | ||||||
| 
 | 
 | ||||||
|     p = find_key(key, 1, value); |     assert(value != NULL); | ||||||
|  |     p = find_key(key, value); | ||||||
|     if (p == NULL) |     if (p == NULL) | ||||||
|         return -1; |         return -1; | ||||||
|     else |     else | ||||||
|  | @ -300,7 +304,7 @@ PyThread_set_key_value(int key, void *value) | ||||||
| void * | void * | ||||||
| PyThread_get_key_value(int key) | PyThread_get_key_value(int key) | ||||||
| { | { | ||||||
|     struct key *p = find_key(key, 0, NULL); |     struct key *p = find_key(key, NULL); | ||||||
| 
 | 
 | ||||||
|     if (p == NULL) |     if (p == NULL) | ||||||
|         return NULL; |         return NULL; | ||||||
|  |  | ||||||
|  | @ -389,11 +389,20 @@ PyThread_delete_key(int key) | ||||||
|     TlsFree(key); |     TlsFree(key); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* We must be careful to emulate the strange semantics implemented in thread.c,
 | ||||||
|  |  * where the value is only set if it hasn't been set before. | ||||||
|  |  */ | ||||||
| int | int | ||||||
| PyThread_set_key_value(int key, void *value) | PyThread_set_key_value(int key, void *value) | ||||||
| { | { | ||||||
|     BOOL ok; |     BOOL ok; | ||||||
|  |     void *oldvalue; | ||||||
| 
 | 
 | ||||||
|  |     assert(value != NULL); | ||||||
|  |     oldvalue = TlsGetValue(key); | ||||||
|  |     if (oldvalue != NULL) | ||||||
|  |         /* ignore value if already set */ | ||||||
|  |         return 0; | ||||||
|     ok = TlsSetValue(key, value); |     ok = TlsSetValue(key, value); | ||||||
|     if (!ok) |     if (!ok) | ||||||
|         return -1; |         return -1; | ||||||
|  |  | ||||||
|  | @ -627,6 +627,9 @@ int | ||||||
| PyThread_set_key_value(int key, void *value) | PyThread_set_key_value(int key, void *value) | ||||||
| { | { | ||||||
|     int fail; |     int fail; | ||||||
|  |     void *oldValue = pthread_getspecific(key); | ||||||
|  |     if (oldValue != NULL) | ||||||
|  |         return 0; | ||||||
|     fail = pthread_setspecific(key, value); |     fail = pthread_setspecific(key, value); | ||||||
|     return fail ? -1 : 0; |     return fail ? -1 : 0; | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner