tags:

views:

263

answers:

6

I'm having trouble passing a pointer to a structure as an argument to a thread cancellation cleanup handler. Here's some sample code that blows up when it hits the compiler. Any idea what I'm doing wrong?

#include <pthread.h>

typedef struct struct_def {
     /* data */
} struct_def;

struct_def *ptr_to_struct_def;

void *
thread_function(void *arg)
{
     pthread_cleanup_push(cleanup, (void *)ptr_to_struct_def); /* correct? */

     /* function continues */
}

int
main()
{
     int err;
     pthread_t tid;

     err = pthread_create(&tid1, NULL, thread_function, (void *)1);

     /* main continues */
}
+1  A: 
Nikolai N Fetissov
+1 for taking the time to check the header file.
Gonzalo
A: 

With that code, the ptr_to_struct_def is undefined/uninitialized that cannot work. It should point to some instance of struct_def.

Also I think it is quite uncommon to pass (void*)1 for unused arguments, just use 0 if you don't use the value.

Steffen
A: 
pthread_cleanup_push(cleanup, (void *)ptr_to_struct_def);
//-------------------^^^^^^^  where is this function defined/declared?
Miroslav Bajtoš
+1  A: 

The main problem is that you are missing the call to

pthread_cleanup_pop(0)

after the 'function continues' comment. That will make the compiler fail. Check out sample code using push/pop at opengroup.org.

You also have a few other problems there, as pointed out in other answers.

Here is something that at least compiles after fixing all the compiler errors:

#include <pthread.h>

typedef struct struct_def {
         /* data */
} struct_def;

struct_def *ptr_to_struct_def;

void cleanup (void *arg)
{
      /* Do your cleanup for the thread here */
}

void *
thread_function(void *arg)
{
    pthread_cleanup_push(cleanup, (void *)ptr_to_struct_def); /* correct? */
    /* Function continues */
    pthread_cleanup_pop (0);
}

int
main()
{
    int err;
    pthread_t tid;

    err = pthread_create(&tid, NULL, thread_function, (void *)1);
    /* main continues */
}
Gonzalo
Good catch! I hate macros that don't expand to complete compilable blocks ...
Nikolai N Fetissov
A: 

You don't need the pointer (notice I removed the typedef):

typedef struct struct_def {
 /* data */
} struct_def;

struct_def *ptr_to_struct_def;

void *
thread_function(void *arg)
{
     pthread_cleanup_push(cleanup, (void *)ptr_to_struct_def); /* correct? */

     /* function continues */
}

int
main()
{
     int err;
     pthread_t tid;

     err = pthread_create(&tid1, NULL, thread_function, (void *)1);

     /* main continues */
}
Richard Pennington
A: 

typedef struct {

} struct_def;

struct_def *ptr_to_struct_def;

void * thread_function(void *arg)

int main() { int err,iResult; pthread_attr_t sThreadAttr; iResult = pthread_attr_init(&sThreadAttr); assert(iResult==0);

 pthread_t tid;

 err = pthread_create(&tid1, &sThreadAttr, thread_function, (void *)&ptr_to_struct_def);

iResult = pthread_join(sThread, NULL); assert(iResult==0);

 /* main continues */

else

thread_function();

endif

// the end return 0; }

void * thread_function(void *arg) { }

Kev