Fix start_world not resuming all threads on Darwin
authorDemyan Kimitsa <demyan.kimitsa@gmail.com>
Tue, 28 Aug 2018 16:40:47 +0000 (19:40 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Thu, 30 Aug 2018 13:31:46 +0000 (16:31 +0300)
commit59c82a57ac38442465fb002c26fcb83e48d7d0af
tree617a4ef232f6c203991f6b70563b5606f7f29016
parent11464bbb9e160257e148be139e830090a7b808a5
Fix start_world not resuming all threads on Darwin

Issue #231 (bdwgc).

This happens due mach thread ports are released in GC_stop_world as
a result in some cases the system creates new one and GC_start_world
will not find the thread to resume; in turn, the threads will stay
suspended.  When this happens to GDC threads, the application is
terminated as the message loop is halt.

The high-level description of the change: thread mach port is not
deallocated when thread is saved in GC_mach_threads as it causes thread
not being resumed as thread port object can be changed; threads are now
being suspended without check of suspend_count (as it can be suspended
by client); the logic of resume is changed, now the primary cycle
iterates threads to resume in GC_mach_threads.

* darwin_stop_world.c (struct GC_mach_thread): Rename already_suspended
filed to suspended.
* darwin_stop_world.c [!GC_NO_THREADS_DISCOVERY]
(GC_suspend_thread_list): Add my_task argument; remove info an outCount
local variables; call mach_port_deallocate uless threaded is added to
GC_mach_threads; do not call thread_info; update the relevant comments.
* darwin_stop_world.c [!GC_NO_THREADS_DISCOVERY] (GC_stop_world):
Remove i local variable; do not call mach_port_deallocate for prevlist
items; add comment.
* darwin_stop_world.c (GC_thread_resume): Call WARN instead of ABORT
if thread_resume failed.
* darwin_stop_world.c [!GC_NO_THREADS_DISCOVERY] (GC_start_world):
Initialize j to listcount; iterate over GC_mach_threads in the outer
loop; if thread is suspended then find it in act_list; if found then
resume thread; call mach_port_deallocate for act_list items.
darwin_stop_world.c