summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorChristian Heimes <christian@python.org>2022-07-27 18:28:06 (GMT)
committerGitHub <noreply@github.com>2022-07-27 18:28:06 (GMT)
commit0fe645d6fd22a6f57e777a29e65cf9a4ff9785ae (patch)
treea6222de1305545869eed745741bbf1f1b3e5f728 /Python
parent226d02bb109d08601fbccd645e9d67aee2e5bcdc (diff)
downloadcpython-0fe645d6fd22a6f57e777a29e65cf9a4ff9785ae.zip
cpython-0fe645d6fd22a6f57e777a29e65cf9a4ff9785ae.tar.gz
cpython-0fe645d6fd22a6f57e777a29e65cf9a4ff9785ae.tar.bz2
gh-95174: Add pthread stubs for WASI (GH-95234)
Co-authored-by: Brett Cannon <brett@python.org>
Diffstat (limited to 'Python')
-rw-r--r--Python/thread.c18
-rw-r--r--Python/thread_pthread.h4
-rw-r--r--Python/thread_pthread_stubs.h185
3 files changed, 201 insertions, 6 deletions
diff --git a/Python/thread.c b/Python/thread.c
index d321121..e206a69 100644
--- a/Python/thread.c
+++ b/Python/thread.c
@@ -55,8 +55,15 @@ PyThread_init_thread(void)
PyThread__init_thread();
}
-#if defined(_POSIX_THREADS)
-# define PYTHREAD_NAME "pthread"
+#if defined(HAVE_PTHREAD_STUBS)
+# define PYTHREAD_NAME "pthread-stubs"
+# include "thread_pthread_stubs.h"
+#elif defined(_POSIX_THREADS)
+# if defined(__EMSCRIPTEN__) || !defined(__EMSCRIPTEN_PTHREADS__)
+# define PYTHREAD_NAME "pthread-stubs"
+# else
+# define PYTHREAD_NAME "pthread"
+# endif
# include "thread_pthread.h"
#elif defined(NT_THREADS)
# define PYTHREAD_NAME "nt"
@@ -171,7 +178,9 @@ PyThread_GetInfo(void)
}
PyStructSequence_SET_ITEM(threadinfo, pos++, value);
-#ifdef _POSIX_THREADS
+#ifdef HAVE_PTHREAD_STUBS
+ value = Py_NewRef(Py_None);
+#elif defined(_POSIX_THREADS)
#ifdef USE_SEMAPHORES
value = PyUnicode_FromString("semaphore");
#else
@@ -182,8 +191,7 @@ PyThread_GetInfo(void)
return NULL;
}
#else
- Py_INCREF(Py_None);
- value = Py_None;
+ value = Py_NewRef(Py_None);
#endif
PyStructSequence_SET_ITEM(threadinfo, pos++, value);
diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h
index c310d72..1c5b320 100644
--- a/Python/thread_pthread.h
+++ b/Python/thread_pthread.h
@@ -7,7 +7,9 @@
#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
#define destructor xxdestructor
#endif
-#include <pthread.h>
+#ifndef HAVE_PTHREAD_STUBS
+# include <pthread.h>
+#endif
#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
#undef destructor
#endif
diff --git a/Python/thread_pthread_stubs.h b/Python/thread_pthread_stubs.h
new file mode 100644
index 0000000..8b80c0f
--- /dev/null
+++ b/Python/thread_pthread_stubs.h
@@ -0,0 +1,185 @@
+#include "cpython/pthread_stubs.h"
+
+// mutex
+int
+pthread_mutex_init(pthread_mutex_t *restrict mutex,
+ const pthread_mutexattr_t *restrict attr)
+{
+ return 0;
+}
+
+int
+pthread_mutex_destroy(pthread_mutex_t *mutex)
+{
+ return 0;
+}
+
+int
+pthread_mutex_trylock(pthread_mutex_t *mutex)
+{
+ return 0;
+}
+
+int
+pthread_mutex_lock(pthread_mutex_t *mutex)
+{
+ return 0;
+}
+
+int
+pthread_mutex_unlock(pthread_mutex_t *mutex)
+{
+ return 0;
+}
+
+// condition
+int
+pthread_cond_init(pthread_cond_t *restrict cond,
+ const pthread_condattr_t *restrict attr)
+{
+ return 0;
+}
+
+PyAPI_FUNC(int)pthread_cond_destroy(pthread_cond_t *cond)
+{
+ return 0;
+}
+
+int
+pthread_cond_wait(pthread_cond_t *restrict cond,
+ pthread_mutex_t *restrict mutex)
+{
+ return 0;
+}
+
+int
+pthread_cond_timedwait(pthread_cond_t *restrict cond,
+ pthread_mutex_t *restrict mutex,
+ const struct timespec *restrict abstime)
+{
+ return 0;
+}
+
+int
+pthread_cond_signal(pthread_cond_t *cond)
+{
+ return 0;
+}
+
+int
+pthread_condattr_init(pthread_condattr_t *attr)
+{
+ return 0;
+}
+
+int
+pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id)
+{
+ return 0;
+}
+
+// pthread
+int
+pthread_create(pthread_t *restrict thread,
+ const pthread_attr_t *restrict attr,
+ void *(*start_routine)(void *),
+ void *restrict arg)
+{
+ return EAGAIN;
+}
+
+int
+pthread_detach(pthread_t thread)
+{
+ return 0;
+}
+
+PyAPI_FUNC(pthread_t) pthread_self(void)
+{
+ return 0;
+}
+
+int
+pthread_exit(void *retval)
+{
+ exit(0);
+}
+
+int
+pthread_attr_init(pthread_attr_t *attr)
+{
+ return 0;
+}
+
+int
+pthread_attr_setstacksize(
+ pthread_attr_t *attr, size_t stacksize)
+{
+ return 0;
+}
+
+int
+pthread_attr_destroy(pthread_attr_t *attr)
+{
+ return 0;
+}
+
+// pthread_key
+typedef struct {
+ bool in_use;
+ void *value;
+} py_tls_entry;
+
+static py_tls_entry py_tls_entries[PTHREAD_KEYS_MAX] = {0};
+
+int
+pthread_key_create(pthread_key_t *key, void (*destr_function)(void *))
+{
+ if (!key) {
+ return EINVAL;
+ }
+ if (destr_function != NULL) {
+ Py_FatalError("pthread_key_create destructor is not supported");
+ }
+ for (pthread_key_t idx = 0; idx < PTHREAD_KEYS_MAX; idx++) {
+ if (!py_tls_entries[idx].in_use) {
+ py_tls_entries[idx].in_use = true;
+ *key = idx;
+ return 0;
+ }
+ }
+ return EAGAIN;
+}
+
+int
+pthread_key_delete(pthread_key_t key)
+{
+ if (key < 0 || key >= PTHREAD_KEYS_MAX || !py_tls_entries[key].in_use) {
+ return EINVAL;
+ }
+ py_tls_entries[key].in_use = false;
+ py_tls_entries[key].value = NULL;
+ return 0;
+}
+
+
+void *
+pthread_getspecific(pthread_key_t key) {
+ if (key < 0 || key >= PTHREAD_KEYS_MAX || !py_tls_entries[key].in_use) {
+ return NULL;
+ }
+ return py_tls_entries[key].value;
+}
+
+int
+pthread_setspecific(pthread_key_t key, const void *value)
+{
+ if (key < 0 || key >= PTHREAD_KEYS_MAX || !py_tls_entries[key].in_use) {
+ return EINVAL;
+ }
+ py_tls_entries[key].value = (void *)value;
+ return 0;
+}
+
+// let thread_pthread define the Python API
+#include "thread_pthread.h"