@@ -1005,40 +1005,53 @@ _extensions_cache_init(void)
1005
1005
return 0 ;
1006
1006
}
1007
1007
1008
+ static _Py_hashtable_entry_t *
1009
+ _extensions_cache_find_unlocked (PyObject * filename , PyObject * name ,
1010
+ void * * p_key )
1011
+ {
1012
+ if (EXTENSIONS .hashtable == NULL ) {
1013
+ return NULL ;
1014
+ }
1015
+ void * key = hashtable_key_from_2_strings (filename , name , HTSEP );
1016
+ if (key == NULL ) {
1017
+ return NULL ;
1018
+ }
1019
+ _Py_hashtable_entry_t * entry =
1020
+ _Py_hashtable_get_entry (EXTENSIONS .hashtable , key );
1021
+ if (p_key != NULL ) {
1022
+ * p_key = key ;
1023
+ }
1024
+ else {
1025
+ hashtable_destroy_str (key );
1026
+ }
1027
+ return entry ;
1028
+ }
1029
+
1008
1030
static PyModuleDef *
1009
1031
_extensions_cache_get (PyObject * filename , PyObject * name )
1010
1032
{
1011
1033
PyModuleDef * def = NULL ;
1012
- void * key = NULL ;
1013
1034
extensions_lock_acquire ();
1014
1035
1015
- if (EXTENSIONS .hashtable == NULL ) {
1016
- goto finally ;
1017
- }
1018
-
1019
- key = hashtable_key_from_2_strings (filename , name , HTSEP );
1020
- if (key == NULL ) {
1021
- goto finally ;
1022
- }
1023
- _Py_hashtable_entry_t * entry = _Py_hashtable_get_entry (
1024
- EXTENSIONS .hashtable , key );
1036
+ _Py_hashtable_entry_t * entry =
1037
+ _extensions_cache_find_unlocked (filename , name , NULL );
1025
1038
if (entry == NULL ) {
1039
+ /* It was never added. */
1026
1040
goto finally ;
1027
1041
}
1028
1042
def = (PyModuleDef * )entry -> value ;
1029
1043
1030
1044
finally :
1031
1045
extensions_lock_release ();
1032
- if (key != NULL ) {
1033
- PyMem_RawFree (key );
1034
- }
1035
1046
return def ;
1036
1047
}
1037
1048
1038
1049
static int
1039
- _extensions_cache_set (PyObject * filename , PyObject * name , PyModuleDef * def )
1050
+ _extensions_cache_set (PyObject * filename , PyObject * name , PyModuleDef * def ,
1051
+ bool replace )
1040
1052
{
1041
1053
int res = -1 ;
1054
+ assert (def != NULL );
1042
1055
extensions_lock_acquire ();
1043
1056
1044
1057
if (EXTENSIONS .hashtable == NULL ) {
@@ -1047,32 +1060,33 @@ _extensions_cache_set(PyObject *filename, PyObject *name, PyModuleDef *def)
1047
1060
}
1048
1061
}
1049
1062
1050
- void * key = hashtable_key_from_2_strings (filename , name , HTSEP );
1051
- if (key == NULL ) {
1052
- goto finally ;
1053
- }
1054
-
1055
1063
int already_set = 0 ;
1056
- _Py_hashtable_entry_t * entry = _Py_hashtable_get_entry (
1057
- EXTENSIONS .hashtable , key );
1064
+ void * key = NULL ;
1065
+ _Py_hashtable_entry_t * entry =
1066
+ _extensions_cache_find_unlocked (filename , name , & key );
1058
1067
if (entry == NULL ) {
1068
+ /* It was never added. */
1059
1069
if (_Py_hashtable_set (EXTENSIONS .hashtable , key , def ) < 0 ) {
1060
- PyMem_RawFree (key );
1061
1070
PyErr_NoMemory ();
1062
1071
goto finally ;
1063
1072
}
1073
+ /* The hashtable owns the key now. */
1074
+ key = NULL ;
1075
+ }
1076
+ else if (entry -> value == NULL ) {
1077
+ /* It was previously deleted. */
1078
+ entry -> value = def ;
1079
+ }
1080
+ /* We expect it to be static, so it must be the same pointer. */
1081
+ else if ((PyModuleDef * )entry -> value == def ) {
1082
+ /* It was already added. */
1083
+ already_set = 1 ;
1064
1084
}
1065
1085
else {
1066
- if (entry -> value == NULL ) {
1067
- entry -> value = def ;
1068
- }
1069
- else {
1070
- /* We expect it to be static, so it must be the same pointer. */
1071
- assert ((PyModuleDef * )entry -> value == def );
1072
- already_set = 1 ;
1073
- }
1074
- PyMem_RawFree (key );
1086
+ assert (replace );
1087
+ entry -> value = def ;
1075
1088
}
1089
+
1076
1090
if (!already_set ) {
1077
1091
/* We assume that all module defs are statically allocated
1078
1092
and will never be freed. Otherwise, we would incref here. */
@@ -1082,27 +1096,24 @@ _extensions_cache_set(PyObject *filename, PyObject *name, PyModuleDef *def)
1082
1096
1083
1097
finally :
1084
1098
extensions_lock_release ();
1099
+ if (key != NULL ) {
1100
+ hashtable_destroy_str (key );
1101
+ }
1085
1102
return res ;
1086
1103
}
1087
1104
1088
1105
static void
1089
1106
_extensions_cache_delete (PyObject * filename , PyObject * name )
1090
1107
{
1091
- void * key = NULL ;
1092
1108
extensions_lock_acquire ();
1093
1109
1094
1110
if (EXTENSIONS .hashtable == NULL ) {
1095
1111
/* It was never added. */
1096
1112
goto finally ;
1097
1113
}
1098
1114
1099
- key = hashtable_key_from_2_strings (filename , name , HTSEP );
1100
- if (key == NULL ) {
1101
- goto finally ;
1102
- }
1103
-
1104
- _Py_hashtable_entry_t * entry = _Py_hashtable_get_entry (
1105
- EXTENSIONS .hashtable , key );
1115
+ _Py_hashtable_entry_t * entry =
1116
+ _extensions_cache_find_unlocked (filename , name , NULL );
1106
1117
if (entry == NULL ) {
1107
1118
/* It was never added. */
1108
1119
goto finally ;
@@ -1120,9 +1131,6 @@ _extensions_cache_delete(PyObject *filename, PyObject *name)
1120
1131
1121
1132
finally :
1122
1133
extensions_lock_release ();
1123
- if (key != NULL ) {
1124
- PyMem_RawFree (key );
1125
- }
1126
1134
}
1127
1135
1128
1136
static void
@@ -1337,7 +1345,7 @@ update_global_state_for_extension(PyThreadState *tstate,
1337
1345
PyModuleDef * cached = _extensions_cache_get (path , name );
1338
1346
assert (cached == NULL || cached == def );
1339
1347
#endif
1340
- if (_extensions_cache_set (path , name , def ) < 0 ) {
1348
+ if (_extensions_cache_set (path , name , def , false ) < 0 ) {
1341
1349
return -1 ;
1342
1350
}
1343
1351
}
0 commit comments