You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Erwin De Wolff <er...@hermes.si> on 2003/02/21 15:06:38 UTC

Problem with the queues

Dear developers

My application uses queues and I notice that I had some difficulties when
reaching the end and start of the queue. I'm using the latest (21 febr 2003)
snapshot of apr and apr-util. Platforms on which it occurs, Windows and
Linux.
To make the problem more accessible I use most of the same code as the
testqueue.c provided in the distribution. Only to simplify I use one
producer and one consumer only and a queue of size 1. The producer pushes
values 0,1,2,3,... and the consumer pops them one by one. The following
output is obtained:

	0: value 0 succesfully pushed.
	1: value 1 succesfully pushed.
	        0: value 1 succesfully popped.
	2: value 2 succesfully pushed.
      	  1: value 2 succesfully popped.
	3: value 3 succesfully pushed.
      	  2: value 3 succesfully popped.
	        3: value 3 succesfully popped.

You can notice a few things:
1. value 0 is never popped
2. there are two values pushed on a queue of size 1!
3. value 3 is popped twice on a queue of size 1.

I don't think I made a mistake in the code, but just for those who might
doubt that, I attached the used code.


#include "apr.h"
#include "apr_pools.h"
#include "apr_thread_proc.h"
#include "apr_queue.h"
#include "apr_time.h"

#define TESTSIZE 4 
apr_pool_t *pool;


void* APR_THREAD_FUNC producer(apr_thread_t * thread_a, void* data_a){
	int i;
	apr_status_t rv;
    apr_queue_t *q = (apr_queue_t*)data_a;
	int *val;
	
	for (i=0; i<TESTSIZE; i++){
		val = apr_pcalloc(pool, sizeof(int));
		*val = i;
 		do {
			rv = apr_queue_push(q, val);
		} while (rv == APR_EINTR);
		if (rv==APR_SUCCESS){
			printf("%d: value %d succesfully pushed.\n", i,
*val);
		}
		rv == -1; //just to be sure we aren't checking the same rv
twice
	}
	return (NULL);
}

void* APR_THREAD_FUNC consumer(apr_thread_t * thread_a, void* data_a){
	void * v;
	int result;
    apr_queue_t *q = (apr_queue_t*)data_a;
	int i = 0;
	apr_status_t rv;

	apr_sleep(APR_USEC_PER_SEC); //just to be sure the producer is first
	while (i<TESTSIZE){
		do {
			rv = apr_queue_pop(q,&v);
		} while (rv == APR_EINTR);
		if (rv == APR_SUCCESS){
			result = **(int **)v;
			printf("\t%d: value %d succesfully popped.\n", i,
result);
			i++;
		}
		rv = -1; //just to be sure that rv is really a succes
	}
	return (NULL);
}

int
main(){
	
    apr_queue_t *q;
	apr_thread_t* prod;
	apr_thread_t* cons;
	apr_status_t prod_rv;
	apr_status_t cons_rv;
	char dummy;

	apr_initialize();
	apr_pool_create(&pool, NULL);
	/* Creating a queue of size 1 */
	apr_queue_create(&q,1,pool);
         
	/* Creating two threads, producer(prod) and consumer(cons) */
	apr_thread_create(&prod, NULL, producer, q, pool);
	apr_thread_create(&cons, NULL, consumer, q, pool);
	apr_thread_join(&prod_rv, prod);
	apr_thread_join(&cons_rv, cons);
	apr_pool_destroy(pool);
	apr_terminate();
	printf("hit <ENTER> to end...");
	scanf("%c", &dummy);
	return 0;
}