2222
2323#ifndef WIN32
2424#include <dlfcn.h>
25-
26- // This is a dict containing a mapping of lib name to "handle"
27- // as returned by `dlopen()`.
28- // Dict[str, int]
29- static PyObject * dlopen_cache ;
30-
31- // This is a dict containing a mapping of (lib_name, symbol_name) to
32- // the raw address as returned by `dlsym()`.
33- // Dict[Tuple[str, str], int]
34- static PyObject * dlsym_cache ;
3525#endif
3626
3727int used_in_vtable (PyObject * value );
@@ -638,20 +628,29 @@ int _PyClassLoader_HasPrimitiveArgs(PyCodeObject* code) {
638628}
639629
640630#ifndef WIN32
641- static PyObject * invoke_native_helper = NULL ;
642631
643632static inline int import_invoke_native () {
644- if (__builtin_expect (invoke_native_helper == NULL , 0 )) {
633+ if (__builtin_expect (Ci_GetInvokeNativeHelper () == NULL , 0 )) {
645634 PyObject * native_utils = PyImport_ImportModule ("__static__.native_utils" );
646635 if (native_utils == NULL ) {
647636 return -1 ;
648637 }
649- invoke_native_helper =
650- PyObject_GetAttrString (native_utils , "invoke_native" );
638+ PyObject * helper = PyObject_GetAttrString (native_utils , "invoke_native" );
651639 Py_DECREF (native_utils );
652- if (invoke_native_helper == NULL ) {
640+ if (helper == NULL ) {
641+ return -1 ;
642+ }
643+ if (!PyFunction_Check (helper )) {
644+ PyErr_Format (
645+ PyExc_TypeError ,
646+ "Expected __static__.native_utils.invoke_native to be a function, "
647+ "got %s" ,
648+ Py_TYPE (helper )-> tp_name );
649+ Py_DECREF (helper );
653650 return -1 ;
654651 }
652+ Ci_SetInvokeNativeHelper ((PyFunctionObject * )helper );
653+ Py_DECREF (helper );
655654 }
656655 return 0 ;
657656}
@@ -707,7 +706,7 @@ PyObject* _PyClassloader_InvokeNativeFunction(
707706 return NULL ;
708707 }
709708 PyObject * res = PyObject_CallFunction (
710- invoke_native_helper ,
709+ Ci_GetInvokeNativeHelper () ,
711710 "OOOO" ,
712711 lib_name ,
713712 symbol_name ,
@@ -720,41 +719,45 @@ PyObject* _PyClassloader_InvokeNativeFunction(
720719
721720// Returns the size of the dlsym_cache dict (0 if uninitialized)
722721PyObject * _PyClassloader_SizeOf_DlSym_Cache () {
723- if (dlsym_cache == NULL ) {
722+ PyObject * cache = Ci_GetDlsymCache ();
723+ if (cache == NULL ) {
724724 return PyLong_FromLong (0 );
725725 }
726- Py_ssize_t size = PyDict_Size (dlsym_cache );
726+ Py_ssize_t size = PyDict_Size (cache );
727727 return PyLong_FromSsize_t (size );
728728}
729729
730730// Returns the size of the dlopen_cache dict (0 if uninitialized)
731731PyObject * _PyClassloader_SizeOf_DlOpen_Cache () {
732- if (dlopen_cache == NULL ) {
732+ PyObject * cache = Ci_GetDlopenCache ();
733+ if (cache == NULL ) {
733734 return PyLong_FromLong (0 );
734735 }
735- Py_ssize_t size = PyDict_Size (dlopen_cache );
736+ Py_ssize_t size = PyDict_Size (cache );
736737 return PyLong_FromSsize_t (size );
737738}
738739
739740// Clears the dlsym_cache dict
740741void _PyClassloader_Clear_DlSym_Cache () {
741- if (dlsym_cache != NULL ) {
742- PyDict_Clear (dlsym_cache );
742+ PyObject * cache = Ci_GetDlsymCache ();
743+ if (cache != NULL ) {
744+ PyDict_Clear (cache );
743745 }
744746}
745747
746748// Clears the dlopen_cache dict
747749void _PyClassloader_Clear_DlOpen_Cache () {
748- if (dlopen_cache != NULL ) {
750+ PyObject * cache = Ci_GetDlopenCache ();
751+ if (cache != NULL ) {
749752 PyObject * name , * handle ;
750753 Py_ssize_t i = 0 ;
751- while (PyDict_Next (dlopen_cache , & i , & name , & handle )) {
754+ while (PyDict_Next (cache , & i , & name , & handle )) {
752755 void * raw_handle = PyLong_AsVoidPtr (handle );
753756 // Ignore errors - we can't do much even if they occur
754757 dlclose (raw_handle );
755758 }
756759
757- PyDict_Clear (dlopen_cache );
760+ PyDict_Clear (cache );
758761 }
759762}
760763
@@ -784,14 +787,17 @@ static void* classloader_lookup_sharedlib(PyObject* lib_name) {
784787 PyObject * val = NULL ;
785788
786789 // Ensure cache exists
787- if (dlopen_cache == NULL ) {
788- dlopen_cache = PyDict_New ();
789- if (dlopen_cache == NULL ) {
790+ PyObject * dl_cache = Ci_GetDlopenCache ();
791+ if (dl_cache == NULL ) {
792+ dl_cache = PyDict_New ();
793+ if (dl_cache == NULL ) {
790794 return NULL ;
791795 }
796+ Ci_SetDlopenCache ((PyDictObject * )dl_cache );
797+ Py_DECREF (dl_cache );
792798 }
793799
794- val = PyDict_GetItem (dlopen_cache , lib_name );
800+ val = PyDict_GetItem (dl_cache , lib_name );
795801 if (val != NULL ) {
796802 // Cache hit
797803 return PyLong_AsVoidPtr (val );
@@ -808,7 +814,7 @@ static void* classloader_lookup_sharedlib(PyObject* lib_name) {
808814 if (val == NULL ) {
809815 return NULL ;
810816 }
811- int res = PyDict_SetItem (dlopen_cache , lib_name , val );
817+ int res = PyDict_SetItem (dl_cache , lib_name , val );
812818 Py_DECREF (val );
813819 if (res < 0 ) {
814820 return NULL ;
@@ -875,19 +881,22 @@ void* _PyClassloader_LookupSymbol(PyObject* lib_name, PyObject* symbol_name) {
875881 }
876882
877883 // Ensure cache exists
878- if (dlsym_cache == NULL ) {
879- dlsym_cache = PyDict_New ();
880- if (dlsym_cache == NULL ) {
884+ PyObject * sym_cache = Ci_GetDlsymCache ();
885+ if (sym_cache == NULL ) {
886+ sym_cache = PyDict_New ();
887+ if (sym_cache == NULL ) {
881888 return NULL ;
882889 }
890+ Ci_SetDlsymCache ((PyDictObject * )sym_cache );
891+ Py_DECREF (sym_cache );
883892 }
884893
885894 PyObject * key = PyTuple_Pack (2 , lib_name , symbol_name );
886895 if (key == NULL ) {
887896 return NULL ;
888897 }
889898
890- PyObject * res = PyDict_GetItem (dlsym_cache , key );
899+ PyObject * res = PyDict_GetItem (sym_cache , key );
891900
892901 if (res != NULL ) {
893902 Py_DECREF (key );
@@ -900,7 +909,7 @@ void* _PyClassloader_LookupSymbol(PyObject* lib_name, PyObject* symbol_name) {
900909 return NULL ;
901910 }
902911
903- if (PyDict_SetItem (dlsym_cache , key , res ) < 0 ) {
912+ if (PyDict_SetItem (sym_cache , key , res ) < 0 ) {
904913 Py_DECREF (key );
905914 Py_DECREF (res );
906915 return NULL ;
0 commit comments