Tuesday, June 8, 2010

pthread atexit()

The atexit() function registers a function to be called when a process terminates, via exit() or via return from main(). However, when a pthread is terminated, pthread_exit() does NOT call any of the atexit() functions. There is a similar pthread_cleanup_push() which does get called, but it is expected that pthread_cleanup_push() and pthread_cleanup_pop() are a matching pair in stack order, so it only works if pthread_exit() sits right in the middle between a pair of the push() and pop().

Fortunately, when a pthread exits, it calls the destructor function specified by pthread_key_create(). Although all threads need to use the same destructor, we can write a destructor that calls another function whose pointer is specified by the thread specific data, facilitating thread local destructor.
typedef void (*exit_t)(void);

void thread_local_destructor(void *arg) {
  exit_t destructor = (exit_t) arg;
  arg();
}
It should be a doable exercise to extend this to register an arbitrary number of functions to run at pthread exit.

No comments: