Hi
Debian etch, gcc version 4.1.2
I'm having a bit of a problem returning data from a thread.
This problem probably extends into a 'what is (void **) ?' question as well.
I have one thread retrieving some data off a queue.
Another thread (listening thread) receives data and then kicks off another thread (adding thread) to to add to the queue.
This bit of code is the control for the retrieving thread
Code:
64 char cbuff[RD_BUFF+1];
...
122 while (1) {
123 sleep(1);
124 pthread_mutex_lock(&qu_mutex);
125 if (start != NULL ) {
126 snprintf(str,MAXLINE-1, "MAIN : Calling collector thread \n");
127 do_log(fd, str);
128 //memset(&event,'\0',sizeof(event));
129 memset(cbuff,'\0',RD_BUFF+1);
130 pthread_create(&collect_tid, attr, eventCollector, (void *)(&cbuff));
131 pthread_join(collect_tid,(void *)cbuff);
132 snprintf(str,MAXLINE-1, "MAIN : Received from collector thread %s\n",cbuff);
133 do_log(fd, str);
134 qu_log();
135 }
136 pthread_mutex_unlock(&qu_mutex);
137 }
Given I intend to wait for the completion of thread execution it hardly seems worth having a thread here. However, I shall for the moment persist.
The retrieving thread removes an element at the start of the queue (FIFO arrangement) and readjusts the pointer to the start of the queue.
Code:
288 void *eventCollector(void *data){
289 // gets an event from the event queue
290 //struct ii_thdata *ptr ;
291 char *ptr ;
292 char str[MAXLINE];
293
294 //ptr = (struct ii_thdata *) data;
295 //memset(ptr,'\0',sizeof(ii_thdata));
296 ptr = ( char *) data;
297 memset(ptr,'\0',RD_BUFF+1);
298 if (start != NULL) {
299 strncpy(ptr,start->buff,RD_BUFF);
300 snprintf(str,MAXLINE-1, "EVCOLL : Queue start address before deletion %x\n",start);
301 do_log(fd, str);
302 qu_del(1);
303 snprintf(str,MAXLINE-1, "EVCOLL : Queue start address after deletion %x\n",start);
304 do_log(fd, str);
305 }
306 pthread_exit((void*)ptr);
307 }
308
I am not getting back the data correctly in L131. L132 prints out
Code:
Thu Jun 12 22:04:59 2008 MAIN : Received from collector thread �F� is test buffer 8
fairly consistently. I have a fixed data set to test this with and the only variation is in the digit.
Here's some log content showing addition to the queue, demonstrating the queue data isn't corrupt on addition. (Code for queue addition isn't shown here.)
Code:
40 Thu Jun 12 22:04:41 2008 EVADD : In eventAdd
41 Thu Jun 12 22:04:41 2008 EVADD : received data "This is test buffer 1"
42 Thu Jun 12 22:04:41 2008 EVADD : Added "This is test buffer 1" to queue
43 Thu Jun 12 22:04:41 2008 QULOG : Queue start element address 0x804d7f8
44 Thu Jun 12 22:04:41 2008 QULOG : Queue element This is test buffer 0 (0x804d7f8)
45 Thu Jun 12 22:04:41 2008 QULOG : Queue element This is test buffer 1 (0x804dc98)
46 Thu Jun 12 22:04:41 2008 EVADD : Leaving eventAdd
So ... it appears I get the data into the queue allright.
The prototypes of pthread_create and pthread_join are
Code:
int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg);
int pthread_join(pthread_t th, void **thread_return);
I simply don't understand how to change cbuff to a void * to pass it in, nor how to get the data out again using void ** .
I understand that void * is a pointer to something, the shape of which is unknown at compile time.
I understand that one cannot deference a void *.
I interpret char ** as a pointer to a pointer to a char
I have used char ** for an array of strings and int ** for a matrix of integers, similarly for float ** and double **.
I can therefore interpret void ** as a pointer to a pointer to an object of unknown shape or size.
But I am stumped w.r.t. converting from a void ** to anything 'useful' e.g. char, char * .
I'm not understanding void ** and void * well enough to be able to take a char[] or char * and convert between the two.
Can anyone help here?
Regards
Lesley