Skip to content

Commit 89c4dab

Browse files
authored
Merge pull request #45 from benoitc/feature/owngil-erlang-api-tests
Add OWN_GIL tests for Channel, ByteChannel, and Buffer operations
2 parents efd4400 + 81890ac commit 89c4dab

File tree

3 files changed

+695
-1
lines changed

3 files changed

+695
-1
lines changed

c_src/py_callback.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3958,6 +3958,63 @@ static int create_erlang_module(void) {
39583958
Py_DECREF(ext_globals);
39593959
}
39603960

3961+
/* Add atom() wrapper with caching for OWN_GIL subinterpreters.
3962+
* In OWN_GIL mode, the Python package (_erlang_impl) is not imported,
3963+
* so erlang.atom() isn't available. This adds it directly to the C module.
3964+
*/
3965+
const char *atom_wrapper_code =
3966+
"_atom_cache = {}\n"
3967+
"_MAX_USER_ATOMS = 10000\n"
3968+
"def atom(name):\n"
3969+
" '''Create or retrieve a cached atom.\n"
3970+
" \n"
3971+
" Args:\n"
3972+
" name: String name for the atom\n"
3973+
" \n"
3974+
" Returns:\n"
3975+
" An erlang.Atom object\n"
3976+
" \n"
3977+
" Raises:\n"
3978+
" RuntimeError: If atom limit (10000) is reached\n"
3979+
" '''\n"
3980+
" if name in _atom_cache:\n"
3981+
" return _atom_cache[name]\n"
3982+
" if len(_atom_cache) >= _MAX_USER_ATOMS:\n"
3983+
" raise RuntimeError('Atom limit reached')\n"
3984+
" import erlang\n"
3985+
" result = erlang._atom(name)\n"
3986+
" _atom_cache[name] = result\n"
3987+
" return result\n"
3988+
"\n"
3989+
"import erlang\n"
3990+
"erlang.atom = atom\n"
3991+
"erlang._atom_cache = _atom_cache\n";
3992+
3993+
PyObject *atom_globals = PyDict_New();
3994+
if (atom_globals != NULL) {
3995+
PyObject *builtins = PyEval_GetBuiltins();
3996+
PyDict_SetItemString(atom_globals, "__builtins__", builtins);
3997+
3998+
/* Import erlang module into globals so the code can reference it */
3999+
PyObject *sys_modules = PySys_GetObject("modules");
4000+
if (sys_modules != NULL) {
4001+
PyObject *erlang_mod = PyDict_GetItemString(sys_modules, "erlang");
4002+
if (erlang_mod != NULL) {
4003+
PyDict_SetItemString(atom_globals, "erlang", erlang_mod);
4004+
}
4005+
}
4006+
4007+
PyObject *result = PyRun_String(atom_wrapper_code, Py_file_input, atom_globals, atom_globals);
4008+
if (result == NULL) {
4009+
/* Non-fatal - atom() just won't be available */
4010+
PyErr_Print();
4011+
PyErr_Clear();
4012+
} else {
4013+
Py_DECREF(result);
4014+
}
4015+
Py_DECREF(atom_globals);
4016+
}
4017+
39614018
return 0;
39624019
}
39634020

0 commit comments

Comments
 (0)