@@ -50,15 +50,19 @@ static struct dso * _Atomic head, * _Atomic tail;
5050
5151#ifdef _REENTRANT
5252static thread_local struct dso * thread_local_tail ;
53- static pthread_rwlock_t lock ;
53+ static pthread_mutex_t write_lock = PTHREAD_MUTEX_INITIALIZER ;
5454
55- static void dlsync_locked () {
55+ static void dlsync () {
5656 if (!thread_local_tail ) {
5757 thread_local_tail = head ;
5858 }
59+ if (!thread_local_tail -> next ) {
60+ return ;
61+ }
62+ dbg ("dlsync: catching up %p %p" , thread_local_tail , tail );
5963 while (thread_local_tail -> next ) {
6064 struct dso * p = thread_local_tail -> next ;
61- dbg ("dlsync_locked : %s mem_addr=%p "
65+ dbg ("dlsync : %s mem_addr=%p "
6266 "mem_size=%zu table_addr=%p table_size=%zu" ,
6367 p -> name ,
6468 p -> mem_addr ,
@@ -76,6 +80,7 @@ static void dlsync_locked() {
7680 }
7781 thread_local_tail = p ;
7882 }
83+ dbg ("dlsync: done" );
7984}
8085
8186// This function is called from emscripten_yield which itself is called whenever
@@ -89,38 +94,31 @@ void _emscripten_thread_sync_code() {
8994 if (skip_dlsync ) {
9095 return ;
9196 }
92- skip_dlsync = true;
9397 ensure_init ();
98+ if (!thread_local_tail ) {
99+ thread_local_tail = head ;
100+ }
94101 if (thread_local_tail != tail ) {
95- dbg ("emscripten_thread_sync_code: catching up %p %p" , thread_local_tail , tail );
96- pthread_rwlock_rdlock (& lock );
97- dlsync_locked ();
98- pthread_rwlock_unlock (& lock );
99- dbg ("emscripten_thread_sync_code: done" );
102+ skip_dlsync = true;
103+ dlsync ();
104+ skip_dlsync = false;
100105 }
101- skip_dlsync = false;
102- }
103-
104- static void do_read_lock () {
105- skip_dlsync = true;
106- pthread_rwlock_rdlock (& lock );
107106}
108107
109108static void do_write_lock () {
110109 // Once we have the lock we want to avoid automatic code sync as that would
111110 // result in a deadlock.
112111 skip_dlsync = true;
113- pthread_rwlock_wrlock ( & lock );
112+ pthread_mutex_lock ( & write_lock );
114113}
115114
116- static void do_unlock () {
117- pthread_rwlock_unlock ( & lock );
115+ static void do_write_unlock () {
116+ pthread_mutex_unlock ( & write_lock );
118117 skip_dlsync = false;
119118}
120119#else
121- #define do_unlock ()
122- #define do_read_lock ()
123120#define do_write_lock ()
121+ #define do_write_unlock ()
124122#endif
125123
126124static void error (const char * fmt , ...) {
@@ -190,14 +188,14 @@ static void dlopen_js_onsuccess(struct dso* dso, struct async_data* data) {
190188 dso -> mem_addr ,
191189 dso -> mem_size );
192190 load_library_done (dso );
193- do_unlock ();
191+ do_write_lock ();
194192 data -> onsuccess (data -> user_data , dso );
195193 free (data );
196194}
197195
198196static void dlopen_js_onerror (struct dso * dso , struct async_data * data ) {
199197 dbg ("dlopen_js_onerror: dso=%p" , dso );
200- do_unlock ();
198+ do_write_unlock ();
201199 data -> onerror (data -> user_data );
202200 free (dso );
203201 free (data );
@@ -219,7 +217,7 @@ static void ensure_init() {
219217 load_library_done (p );
220218 assert (head );
221219 }
222- do_unlock ();
220+ do_write_unlock ();
223221}
224222
225223void * dlopen (const char * file , int flags ) {
@@ -235,7 +233,7 @@ void* dlopen(const char* file, int flags) {
235233 do_write_lock ();
236234#ifdef _REENTRANT
237235 // Make sure we are in sync before loading any new DSOs.
238- dlsync_locked ();
236+ dlsync ();
239237#endif
240238
241239 /* Search for the name to see if it's already loaded */
@@ -260,8 +258,9 @@ void* dlopen(const char* file, int flags) {
260258 dbg ("dlopen_js: success: %p" , p );
261259 load_library_done (p );
262260end :
263- do_unlock ();
261+ do_write_unlock ();
264262 pthread_setcancelstate (cs , 0 );
263+ dbg ("dlopen: %s done" , file );
265264 return p ;
266265}
267266
@@ -275,7 +274,7 @@ void emscripten_dlopen(const char* filename, int flags, void* user_data,
275274 do_write_lock ();
276275 struct dso * p = load_library_start (filename , flags );
277276 if (!p ) {
278- do_unlock ();
277+ do_write_unlock ();
279278 onerror (user_data );
280279 return ;
281280 }
@@ -297,9 +296,7 @@ void* __dlsym(void* restrict p, const char* restrict s, void* restrict ra) {
297296 return 0 ;
298297 }
299298 void * res ;
300- do_read_lock ();
301299 res = _dlsym_js (p , s );
302- do_unlock ();
303300 dbg ("__dlsym done dso:%p res:%p" , p , res );
304301 return res ;
305302}
0 commit comments