/****************************************************************************/
* Author : Samson
* Date : 03/28/2012
* Test platform:
* GNU Linux version 2.6.29.4
* gcc version 4.4.0 20090506 (Red Hat 4.4.0-4) (GCC)
* Description:
*This program is the details of the interaction between the test *pthread_cleanup_push, pthread_cleanup_pop and pthread_exit method function
/****************************************************************************/
#include <pthread.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
static int cleanup_pop_arg = 0;
static int cnt = 0;
static void
cleanup_handler (void *arg)
{
char *str = (char *)arg;
printf ("Called clean-up handler, arg is %s\n", str);
cnt = 0;
}
static void *
thread_start (void *arg)
{
time_t start, curr;
char *str;
char strr[64] = {0};
str = malloc (64);
printf ("New thread started\n");
sprintf (strr, "pusharg\n");
//call pthread_cleanup_push register clean function that when called
//pthread_exit or pthread_cancel function or when pthread_cleanup_pop arg is non-zero.
pthread_cleanup_push (cleanup_handler, strr);
curr = start = time (NULL);
sprintf (str, "this thread: %d called pthread_exit\n", (int) pthread_self());
pthread_exit (str);
//if pthread_cleanup_pop arg is non-zero, execute clean function and pop clean function.
//else only pop register clean function.
pthread_cleanup_pop (cleanup_pop_arg);
return NULL;
}
int
main (int argc, char *argv[])
{
pthread_t thr;
int s;
void *res, *ret;
if (argc > 1)
{
//argv[1] is set pthread_cleanup_pop arg
cleanup_pop_arg = atoi (argv[1]);
}
s = pthread_create (&thr, NULL, thread_start, NULL);
if (s != 0)
handle_error_en (s, "pthread_create");
sleep (2);
s = pthread_join (thr, &res);
if (s != 0)
{
handle_error_en (s, "pthread_join");
}
else
{
printf ("pthread_join velret is %s\n", (char *) res);
}
if (res == PTHREAD_CANCELED)
{
printf ("Thread was canceled; cnt = %d\n", cnt);
}
else
{
printf ("Thread terminated normally; cnt = %d\n", cnt);
}
exit (EXIT_SUCCESS);
}
compile and run:
# ./a.out
New thread started
Called clean-up handler, arg is pusharg
pthread_join velret is this thread: -1207649424 called pthread_exit
Thread terminated normally; cnt = 0
when Comment out that line of code contains pthread_exit compile and run the results as follows:
# ./a.out
New thread started
pthread_join velret is (null)
Thread terminated normally; cnt = 0
//when run with arg 1 to change pthread_cleanup_pop arg result as follows:
# ./a.out 1
New thread started
Called clean-up handler, arg is pusharg
pthread_join velret is (null)
Thread terminated normally; cnt = 0