Skip to content

Commit 7772113

Browse files
committed
use _Py_hashtable_t for lib_codes_to_names
1 parent fd7d3ec commit 7772113

File tree

2 files changed

+63
-35
lines changed

2 files changed

+63
-35
lines changed

Modules/_ssl.c

Lines changed: 62 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,10 @@ typedef struct py_ssl_error_code {
8181
int library, reason;
8282
} py_ssl_error_code;
8383

84-
struct py_ssl_library_code {
84+
typedef struct py_ssl_library_code {
8585
const char *library;
8686
int code;
87-
};
87+
} py_ssl_library_code;
8888

8989
#if defined(MS_WINDOWS) && defined(Py_DEBUG)
9090
/* Debug builds on Windows rely on getting errno directly from OpenSSL.
@@ -479,20 +479,17 @@ static int
479479
ssl_error_fetch_lib_and_reason(_sslmodulestate *state, py_ssl_errcode errcode,
480480
PyObject **lib, PyObject **reason)
481481
{
482-
int rc;
483-
PyObject *key = NULL;
484482
int errlib = ERR_GET_LIB(errcode);
485483
int errrea = ERR_GET_REASON(errcode);
486484

487-
key = PyLong_FromLong(errlib);
488-
if (key == NULL) {
489-
return -1;
490-
}
491-
rc = PyDict_GetItemRef(state->lib_codes_to_names, key, lib);
492-
Py_DECREF(key);
493-
if (rc < 0) {
485+
const void *key1 = (const void *)((uintptr_t)errlib);
486+
const void *val1 = _Py_hashtable_get(state->lib_codes_to_names, key1);
487+
if (val1 == NULL) {
488+
*lib = NULL;
494489
return -1;
495490
}
491+
assert(PyUnicode_CheckExact(val1));
492+
*lib = Py_NewRef((PyObject *)val1);
496493

497494
const void *key2 = (const void *)((uintptr_t)ERR_PACK(errlib, 0, errrea));
498495
const void *val2 = _Py_hashtable_get(state->err_codes_to_names, key2);
@@ -6874,36 +6871,66 @@ py_ht_errcode_to_name_create(void) {
68746871
return NULL;
68756872
}
68766873

6874+
/* internal hashtable (libcode) => (libname [PyObject * (unicode)]) */
6875+
static Py_uhash_t
6876+
py_ht_libcode_to_name_hash(const void *key) {
6877+
return (Py_uhash_t)((uintptr_t)key);
6878+
}
6879+
6880+
static int
6881+
py_ht_libcode_to_name_comp(const void *a, const void *b) {
6882+
return (uintptr_t)a == (uintptr_t)b;
6883+
}
6884+
6885+
static void
6886+
py_ht_libcode_to_name_free(void *value) {
6887+
assert(PyUnicode_CheckExact((PyObject *)value));
6888+
Py_CLEAR(value);
6889+
}
6890+
6891+
static _Py_hashtable_t *
6892+
py_ht_libcode_to_name_create(void) {
6893+
_Py_hashtable_t *table = _Py_hashtable_new_full(
6894+
py_ht_libcode_to_name_hash,
6895+
py_ht_libcode_to_name_comp,
6896+
NULL,
6897+
py_ht_libcode_to_name_free,
6898+
NULL
6899+
);
6900+
if (table == NULL) {
6901+
PyErr_NoMemory();
6902+
return NULL;
6903+
}
6904+
6905+
for (const py_ssl_library_code *p = library_codes; p->library != NULL; p++) {
6906+
const void *key = (const void *)((uintptr_t)p->code);
6907+
PyObject *value = PyUnicode_FromString(p->library);
6908+
if (value == NULL) {
6909+
goto error;
6910+
}
6911+
if (_Py_hashtable_set(table, key, value) < 0) {
6912+
Py_DECREF(value);
6913+
goto error;
6914+
}
6915+
}
6916+
return table;
6917+
error:
6918+
_Py_hashtable_destroy(table);
6919+
return NULL;
6920+
}
6921+
68776922
static int
68786923
sslmodule_init_errorcodes(PyObject *module)
68796924
{
68806925
_sslmodulestate *state = get_ssl_state(module);
6881-
6882-
struct py_ssl_library_code *libcode;
6883-
6884-
/* Mappings for error codes */
68856926
state->err_codes_to_names = py_ht_errcode_to_name_create();
68866927
if (state->err_codes_to_names == NULL) {
68876928
return -1;
68886929
}
6889-
state->lib_codes_to_names = PyDict_New();
6890-
if (state->lib_codes_to_names == NULL)
6930+
state->lib_codes_to_names = py_ht_libcode_to_name_create();
6931+
if (state->lib_codes_to_names == NULL) {
68916932
return -1;
6892-
6893-
libcode = library_codes;
6894-
while (libcode->library != NULL) {
6895-
PyObject *mnemo, *key;
6896-
key = PyLong_FromLong(libcode->code);
6897-
mnemo = PyUnicode_FromString(libcode->library);
6898-
if (key == NULL || mnemo == NULL)
6899-
return -1;
6900-
if (PyDict_SetItem(state->lib_codes_to_names, key, mnemo))
6901-
return -1;
6902-
Py_DECREF(key);
6903-
Py_DECREF(mnemo);
6904-
libcode++;
69056933
}
6906-
69076934
return 0;
69086935
}
69096936

@@ -7072,7 +7099,6 @@ sslmodule_traverse(PyObject *m, visitproc visit, void *arg)
70727099
Py_VISIT(state->PySSLWantWriteErrorObject);
70737100
Py_VISIT(state->PySSLSyscallErrorObject);
70747101
Py_VISIT(state->PySSLEOFErrorObject);
7075-
Py_VISIT(state->lib_codes_to_names);
70767102
Py_VISIT(state->Sock_Type);
70777103

70787104
return 0;
@@ -7099,8 +7125,10 @@ sslmodule_clear(PyObject *m)
70997125
_Py_hashtable_destroy(state->err_codes_to_names);
71007126
state->err_codes_to_names = NULL;
71017127
}
7102-
7103-
Py_CLEAR(state->lib_codes_to_names);
7128+
if (state->lib_codes_to_names != NULL) {
7129+
_Py_hashtable_destroy(state->lib_codes_to_names);
7130+
state->lib_codes_to_names = NULL;
7131+
}
71047132
Py_CLEAR(state->Sock_Type);
71057133
Py_CLEAR(state->str_library);
71067134
Py_CLEAR(state->str_reason);

Modules/_ssl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ typedef struct {
2727
PyObject *PySSLEOFErrorObject;
2828
/* Error mappings */
2929
_Py_hashtable_t *err_codes_to_names;
30-
PyObject *lib_codes_to_names;
30+
_Py_hashtable_t *lib_codes_to_names;
3131
/* socket type from module CAPI */
3232
PyTypeObject *Sock_Type;
3333
/* Interned strings */

0 commit comments

Comments
 (0)