summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/unix/main.c4
-rw-r--r--ports/unix/mpthreadport.c14
-rw-r--r--ports/unix/mpthreadport.h1
3 files changed, 19 insertions, 0 deletions
diff --git a/ports/unix/main.c b/ports/unix/main.c
index 1cf237a2b..8d455fa83 100644
--- a/ports/unix/main.c
+++ b/ports/unix/main.c
@@ -647,6 +647,10 @@ MP_NOINLINE int main_(int argc, char **argv) {
}
#endif
+ #if MICROPY_PY_THREAD
+ mp_thread_deinit();
+ #endif
+
#if defined(MICROPY_UNIX_COVERAGE)
gc_sweep_all();
#endif
diff --git a/ports/unix/mpthreadport.c b/ports/unix/mpthreadport.c
index baca0a2b1..7170379f4 100644
--- a/ports/unix/mpthreadport.c
+++ b/ports/unix/mpthreadport.c
@@ -93,6 +93,19 @@ void mp_thread_init(void) {
sigaction(SIGUSR1, &sa, NULL);
}
+void mp_thread_deinit(void) {
+ pthread_mutex_lock(&thread_mutex);
+ while (thread->next != NULL) {
+ thread_t *th = thread;
+ thread = thread->next;
+ pthread_cancel(th->id);
+ free(th);
+ }
+ pthread_mutex_unlock(&thread_mutex);
+ assert(thread->id == pthread_self());
+ free(thread);
+}
+
// This function scans all pointers that are external to the current thread.
// It does this by signalling all other threads and getting them to scan their
// own registers and stack. Note that there may still be some edge cases left
@@ -127,6 +140,7 @@ void mp_thread_set_state(void *state) {
}
void mp_thread_start(void) {
+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_mutex_lock(&thread_mutex);
for (thread_t *th = thread; th != NULL; th = th->next) {
if (th->id == pthread_self()) {
diff --git a/ports/unix/mpthreadport.h b/ports/unix/mpthreadport.h
index b158ed5bc..dfd2975c2 100644
--- a/ports/unix/mpthreadport.h
+++ b/ports/unix/mpthreadport.h
@@ -29,4 +29,5 @@
typedef pthread_mutex_t mp_thread_mutex_t;
void mp_thread_init(void);
+void mp_thread_deinit(void);
void mp_thread_gc_others(void);