Skip to content

Commit 453cf6a

Browse files
authored
Fix pthread undefined behaviour in thread_create (#308)
It is undefined behaviour for a mutex to be destroyed while it is still locked, and also for a locked mutex to be unlocked by a different thread. These issues can be avoided using a condition variable instead of relying on undefined behaviour of mutexes.
1 parent a1ff62a commit 453cf6a

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

vm/threads.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ typedef struct {
8686
HANDLE lock;
8787
# else
8888
pthread_mutex_t lock;
89+
pthread_cond_t cond;
90+
volatile bool is_ready;
8991
# endif
9092
#endif
9193
} tparams;
@@ -116,6 +118,9 @@ static THREAD_FUN ThreadMain( void *_p ) {
116118
# ifdef NEKO_WINDOWS
117119
ReleaseSemaphore(p.lock,1,NULL);
118120
# else
121+
pthread_mutex_lock(&lp->lock);
122+
lp->is_ready = true;
123+
pthread_cond_signal(&lp->cond);
119124
pthread_mutex_unlock(&lp->lock);
120125
# endif
121126
clean_c_stack(40,clean_c_stack);
@@ -151,17 +156,24 @@ EXTERN int neko_thread_create( thread_main_func init, thread_main_func main, voi
151156
pthread_attr_init(&attr);
152157
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
153158
pthread_mutex_init(&p.lock,NULL);
154-
pthread_mutex_lock(&p.lock);
159+
pthread_cond_init(&p.cond,NULL);
160+
p.is_ready = false;
155161
// force the use of a the GC method to capture created threads
156162
// this function should be defined in gc/gc.h
157163
if( GC_pthread_create((pthread_t*)handle,&attr,&ThreadMain,&p) != 0 ) {
158164
pthread_attr_destroy(&attr);
159165
pthread_mutex_destroy(&p.lock);
166+
pthread_cond_destroy(&p.cond);
160167
return 0;
161168
}
162169
pthread_mutex_lock(&p.lock);
170+
while (!p.is_ready) {
171+
pthread_cond_wait(&p.cond,&p.lock);
172+
}
173+
pthread_mutex_unlock(&p.lock);
163174
pthread_attr_destroy(&attr);
164175
pthread_mutex_destroy(&p.lock);
176+
pthread_cond_destroy(&p.cond);
165177
return 1;
166178
# endif
167179
}

0 commit comments

Comments
 (0)