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;
}