Find the answer to your Linux question:
Results 1 to 3 of 3
gcc is telling me that "data" is undefined on the line "return data;". Does anyone know why? I think it has something to do with pthread_cleanup_pop because the code compiles ...
  1. #1
    Just Joined!
    Join Date
    Oct 2009
    Posts
    7

    pthread_cleanup_pop

    gcc is telling me that "data" is undefined on the line "return data;". Does anyone know why? I think it has something to do with pthread_cleanup_pop because the code compiles when I comment that line. Thoughts?

    Code:
    void* queue_remove(queue_t* queue) 
    {		
    	/* Lock the queue */
    	pthread_mutex_lock(&queue->queue_mutex);
    	
    	/* Push this thread's cleanup handler onto the stack */
    	pthread_cleanup_push(cleanup_handler,(void*)queue);
    	
    	if(queue->num_workers > 0)
    	{
    		/* This loop is to prevent more than one thread from accessing the queue at a time in the event of a spurious wakeup. */
    		while(queue->length == 0)
    		{	
    			/* Wait for queue_add to signal that it has added a new node */
    			pthread_cond_wait(&queue->ready, &queue->queue_mutex);
    		}
    	}
    	
    	/* Temporary node pointer that will allow us to free the node being removed */				
    	node_t *tmp_node;
    	
    	/* Point the first node of the queue to the new temporary node */
    	tmp_node = queue->front;
        
    	/* The second node in the queue is going to become the front so point the front to the second node */
    	queue->front = tmp_node->next;
    	
    	/* Point the item we will be removing to the data portion of the node being removed */
    	void* data = tmp_node->data;
    	
    	/* Decrease the amount of memory being used by the queue by the size of the data being removed. */
    	queue->memory_allocated -= queue->node_size + sizeof(node_t);
    
    	/* Free the node we are removing */
    	free(tmp_node);
    
    	/* Decrease the number of nodes in the queue */
    	queue->length--;
    	
    	/* If the queue becomes empty as a result of removing this element ... */
    	if (queue->front == NULL) 
    	{
    		/* Assign the back of the queue to null */
    		queue->back = NULL;
    	}
    
    	pthread_cleanup_pop(1);
    	
    	return data;
    }

  2. #2
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
    Posts
    8,974
    I think you are onto the problem in that the cause is pthread_cleanup_pop(). According to the man page
    Code:
           The pthread_cleanup_pop() function shall remove the  routine  at  the
           top of the calling thread’s cancellation cleanup stack and optionally
           invoke it (if execute is non-zero).
    Just a guess, but it is this function, and as a result, all automatic variables are fubar. Try a local static variable and return that instead. IE
    Code:
    static void* data = 0;
    void* queue_remove(queue_t* queue) 
    {		
    	/* Lock the queue */
    	pthread_mutex_lock(&queue->queue_mutex);
    	
    	/* Push this thread's cleanup handler onto the stack */
    	pthread_cleanup_push(cleanup_handler,(void*)queue);
    	
    	if(queue->num_workers > 0)
    	{
    		/* This loop is to prevent more than one thread from accessing the queue at a time in the event of a spurious wakeup. */
    		while(queue->length == 0)
    		{	
    			/* Wait for queue_add to signal that it has added a new node */
    			pthread_cond_wait(&queue->ready, &queue->queue_mutex);
    		}
    	}
    	
    	/* Temporary node pointer that will allow us to free the node being removed */				
    	node_t *tmp_node;
    	
    	/* Point the first node of the queue to the new temporary node */
    	tmp_node = queue->front;
        
    	/* The second node in the queue is going to become the front so point the front to the second node */
    	queue->front = tmp_node->next;
    	
    	/* Point the item we will be removing to the data portion of the node being removed */
    	data = tmp_node->data;
    	
    	/* Decrease the amount of memory being used by the queue by the size of the data being removed. */
    	queue->memory_allocated -= queue->node_size + sizeof(node_t);
    
    	/* Free the node we are removing */
    	free(tmp_node);
    
    	/* Decrease the number of nodes in the queue */
    	queue->length--;
    	
    	/* If the queue becomes empty as a result of removing this element ... */
    	if (queue->front == NULL) 
    	{
    		/* Assign the back of the queue to null */
    		queue->back = NULL;
    	}
    
    	pthread_cleanup_pop(1);
    	
    	return data;
    }
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  3. #3
    Just Joined!
    Join Date
    Oct 2009
    Posts
    7
    If multiple threads are accessing this routine won't there be a race condition on data? The queue is unlocked before data is returned.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...