[pypy-commit] pypy cffi-embedding-win32: in-progress: share more code between posix and win32, and use
arigo
pypy.commits at gmail.com
Tue Feb 9 15:18:14 EST 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-embedding-win32
Changeset: r82130:12211c49a141
Date: 2016-02-09 21:17 +0100
http://bitbucket.org/pypy/pypy/changeset/12211c49a141/
Log: in-progress: share more code between posix and win32, and use only
win32 functions available on Windows XP
diff --git a/pypy/module/_cffi_backend/embedding.py b/pypy/module/_cffi_backend/embedding.py
--- a/pypy/module/_cffi_backend/embedding.py
+++ b/pypy/module/_cffi_backend/embedding.py
@@ -84,72 +84,87 @@
return rffi.cast(rffi.INT, res)
# ____________________________________________________________
+
if os.name == 'nt':
- do_startup = r'''
-#include <stdio.h>
-#define WIN32_LEAN_AND_MEAN
+
+ do_includes = r"""
+#define _WIN32_WINNT 0x0501
#include <windows.h>
-RPY_EXPORTED void rpython_startup_code(void);
-RPY_EXPORTED int pypy_setup_home(char *, int);
-static unsigned char _cffi_ready = 0;
-static const char *volatile _cffi_module_name;
+#define CFFI_INIT_HOME_PATH_MAX _MAX_PATH
+static void _cffi_init(void);
+static void _cffi_init_error(const char *msg, const char *extra);
-static void _cffi_init_error(const char *msg, const char *extra)
+static int _cffi_init_home(char *output_home_path)
{
- fprintf(stderr,
- "\nPyPy initialization failure when loading module '%s':\n%s%s\n",
- _cffi_module_name, msg, extra);
-}
-
-BOOL CALLBACK _cffi_init(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *lpContex)
-{
-
- HMODULE hModule;
- TCHAR home[_MAX_PATH];
- rpython_startup_code();
- RPyGilAllocate();
+ HMODULE hModule = 0;
+ DWORD res;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
(LPCTSTR)&_cffi_init, &hModule);
+
if (hModule == 0 ) {
- /* TODO turn the int into a string with FormatMessage */
-
- _cffi_init_error("dladdr() failed: ", "");
- return TRUE;
+ _cffi_init_error("GetModuleHandleEx() failed", "");
+ return -1;
}
- GetModuleFileName(hModule, home, _MAX_PATH);
- if (pypy_setup_home(home, 1) != 0) {
- _cffi_init_error("pypy_setup_home() failed", "");
- return TRUE;
+ res = GetModuleFileName(hModule, output_home_path, CFFI_INIT_HOME_PATH_MAX);
+ if (res >= CFFI_INIT_HOME_PATH_MAX) {
+ return -1;
}
- _cffi_ready = 1;
- fprintf(stderr, "startup succeeded, home %s\n", home);
- return TRUE;
+ return 0;
}
-RPY_EXPORTED
-int pypy_carefully_make_gil(const char *name)
+static void _cffi_init_once(void)
{
- /* For CFFI: this initializes the GIL and loads the home path.
- It can be called completely concurrently from unrelated threads.
- It assumes that we don't hold the GIL before (if it exists), and we
- don't hold it afterwards.
- */
- static INIT_ONCE s_init_once;
+ static LONG volatile lock = 0;
+ static int _init_called = 0;
- _cffi_module_name = name; /* not really thread-safe, but better than
- nothing */
- InitOnceExecuteOnce(&s_init_once, _cffi_init, NULL, NULL);
- return (int)_cffi_ready - 1;
-}'''
+ while (InterlockedCompareExchange(&lock, 1, 0) != 0) {
+ SwitchToThread(); /* spin loop */
+ }
+ if (!_init_called) {
+ _cffi_init();
+ _init_called = 1;
+ }
+ InterlockedCompareExchange(&lock, 0, 1);
+}
+"""
+
else:
- do_startup = r"""
-#include <stdio.h>
+
+ do_includes = r"""
#include <dlfcn.h>
#include <pthread.h>
+#define CFFI_INIT_HOME_PATH_MAX PATH_MAX
+static void _cffi_init(void);
+static void _cffi_init_error(const char *msg, const char *extra);
+
+static int _cffi_init_home(char *output_home_path)
+{
+ Dl_info info;
+ dlerror(); /* reset */
+ if (dladdr(&_cffi_init, &info) == 0) {
+ _cffi_init_error("dladdr() failed: ", dlerror());
+ return -1;
+ }
+ if (realpath(info.dli_fname, output_home_path) == NULL) {
+ perror("realpath() failed");
+ _cffi_init_error("realpath() failed", "");
+ return -1;
+ }
+ return 0;
+}
+
+static void _cffi_init_once(void)
+{
+ static pthread_once_t once_control = PTHREAD_ONCE_INIT;
+ pthread_once(&once_control, _cffi_init);
+}
+"""
+
+do_startup = do_includes + r"""
RPY_EXPORTED void rpython_startup_code(void);
RPY_EXPORTED int pypy_setup_home(char *, int);
@@ -165,17 +180,13 @@
static void _cffi_init(void)
{
- Dl_info info;
- char *home;
+ char home[CFFI_INIT_HOME_PATH_MAX + 1];
rpython_startup_code();
RPyGilAllocate();
- if (dladdr(&_cffi_init, &info) == 0) {
- _cffi_init_error("dladdr() failed: ", dlerror());
+ if (_cffi_init_home(home) != 0)
return;
- }
- home = realpath(info.dli_fname, NULL);
if (pypy_setup_home(home, 1) != 0) {
_cffi_init_error("pypy_setup_home() failed", "");
return;
@@ -191,11 +202,9 @@
It assumes that we don't hold the GIL before (if it exists), and we
don't hold it afterwards.
*/
- static pthread_once_t once_control = PTHREAD_ONCE_INIT;
-
_cffi_module_name = name; /* not really thread-safe, but better than
nothing */
- pthread_once(&once_control, _cffi_init);
+ _cffi_init_once();
return (int)_cffi_ready - 1;
}
"""
More information about the pypy-commit
mailing list