/* Code Example 3 */

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#define NUMBER_OF_KEYS_WE_USE ...
#define MAX_NUMBER_OF_THREADS ...

/* global key to the thread specific data */
pthread_key_t priority_key;

/* function prototypes */
void* client_thread( void* );
void prepare_data( void );
void lump_send( data_t );

int main( void )
{
        int n;
        pthread_t
           thread_id[MAX_NUMBER_OF_THREADS];
        ...
        /* check that the implementation can cope
         * with all the keys we need */
        if ( NUMBER_OF_KEYS_WE_USE >
             PTHREAD_KEYS_MAX ) {
                fprintf( stderr,
                "Not enough keys available\n");
                exit( -1 );
        }
        /* create the keys that we need.  We're
         * going to use "malloc()" to grab
         * some memory and point the thread specific
         * data at it. If the thread dies, we'd like
         *  the system to use "free()" to
         *  release that memory for us
         */
        pthread_key_create( &priority_key, free );
        ...
        /* create the threads */
        pthread_create( &thread_id[n], NULL,
            client_thread, NULL );
        ...
}

void* client_thread( void* arg )
{
        /* grab enough memory to store an int, and
         * store a pointer to that memory as thread
         * specific data
         */
        pthread_setspecific( priority_key,
               malloc( sizeof( int ) ) );
        ...
        prepare_data();
        ...
}

void prepare_data( void )
{
        data_t some_data;
        ...
        /* store the priority value in the
         *  memory pointed to by the thread
         *  specific data
         */

        *((int*)pthread_getspecific(
        priority_key )) = 1;
        ...
        lump_send( some_data );
        ...
}

void lump_send( data_t some_data )
{
        /* act on the value stored in the memory
         *  pointed to by the thread specific data
         */
        switch( *((int*)pthread_getspecific(
             priority_key )) )
        {
        case 1:  /* do one thing */
                break;
        case 2: /* do something else */
                break;
        }
}