eina/ecore: allow threads to be canceled, use in ecore_con.
authorGustavo Sverzut Barbieri <barbieri@profusion.mobi>
Wed, 14 Sep 2016 04:38:58 +0000 (01:38 -0300)
committerGustavo Sverzut Barbieri <barbieri@profusion.mobi>
Wed, 14 Sep 2016 04:47:23 +0000 (01:47 -0300)
commit960e1a1d168ba0044544ca22b05cbf505941f150
tree8c31f0ee79ceaf5f9d13bb8e7d9c3903364b5580
parent5df0b6765ba6b2938e19cae7e8e3a238cf72f800
eina/ecore: allow threads to be canceled, use in ecore_con.

As discussed in the mailing list, many people will use worker threads
to execute blocking syscalls and mandating ecore_thread_check() for
voluntary preemption reduces the ecore_thread usefulness a lot.

A clear example is ecore_con usage of connect() and getaddrinfo() in
threads. If the connect timeout expires, the thread will be cancelled,
but it was blocked on syscalls and they will hang around for long
time. If the application exits, ecore will print an error saying it
can SEGV.

Then enable access to pthread_setcancelstate(PTHREAD_CANCEL_ENABLE)
via eina_thread_cancellable_set(EINA_TRUE), to pthread_cancel() via
eina_thread_cancel(), to pthread_cleanup_push()/pthread_cleanup_pop()
via EINA_THREAD_CLEANUP_PUSH()/EINA_THREAD_CLEANUP_POP() and so on.

Ecore threads will enforce non-cancellable threads on its own code,
but the user may decide to enable that and allow cancellation, that's
not an issue since ecore_thread now plays well and use cleanup
functions.

Ecore con connect/resolve make use of that and enable cancellable
state, efl_net_dialer_tcp benefits a lot from that.

A good comparison of the benefit is to run:

   ./src/examples/ecore/efl_io_copier_example tcp://google.com:1234 :stdout:

before and after. It will timeout after 30s and with this patch the
thread is gone, no ecore error is printed about possible SEGV.
src/lib/ecore/Ecore_Common.h
src/lib/ecore/ecore_thread.c
src/lib/ecore_con/ecore_con.c
src/lib/eina/Eina.h
src/lib/eina/eina_thread.c
src/lib/eina/eina_thread.h