champnim
June 26th, 2008, 02:45 AM
I am facing a strange problem. I have a multi-threaded C program that is communicating with the COM port. I have a dedicated thread to read from the port that remains in an infinite loop to read any incoming data. Whenever something is read my 'read thread' creates a new entry in a global linked list, specifying a code for the thing read as well as the string read itself. When the main thread realises that an entry has been made into the list, it accesses the linked list & after reading the data stored there, it deletes the entry.
Here is my code:
//Code for Linked List
struct fifo
{
int result;
char *info;
struct fifo *next;
}*node;
void add(struct fifo **n,int data,char *text)
{
struct fifo *temp,*node1;
if (*n==NULL)
{
temp=(struct fifo *)malloc(sizeof(struct fifo));
printf("%d is to be stored\n",data);
temp->result=data;
printf("%d is stored\n",temp->result);
temp->info=(char *)malloc(strlen(text)+1);
strcpy(temp->info,text);
temp->next=NULL;
*n=temp;
}
else
{
temp=*n;
while(temp->next!=NULL)
temp=temp->next;
node1=(struct fifo *)malloc(sizeof(struct fifo));
node1->result=data;
node1->info=(char *)malloc(strlen(text)+1);
strcpy(node1->info,text);
node1->next=NULL;
temp->next=node1;
}
}
void del(struct fifo **n)
{
struct fifo *temp;
if (*n==NULL)
{
printf("Linked list is empty\n");
}
else
{
temp=*n;
*n=temp->next;
}
}
//Code for Linked List ends
//Inside read thread that will add to the linked list
//If a particular condition is satisfied
EnterCriticalSection(&critical);
add(&node,50,location); //location holds string read
LeaveCriticalSection(&critical); //exit condition after this
//End of read thread
//Inside main thread that reads & deletes from the linked list
InitializeCriticalSection(&critical);
while(1)
{
if (node==NULL) //idle case
{
printf("Nothing to read\n");
Sleep(4000);
}
else //Linked List is not empty
{
EnterCriticalSection(&critical);
temp=(struct fifo *)malloc(sizeof(struct fifo)); //Read node
printf("%d\n%s\n",node->result,node->info);
op=node->result;
printf("op is %d\n",op);
detail=(char *) malloc (strlen(node->info));
strcpy(detail,node->info);
printf("%s\n",detail);
del(&node); //delete node
LeaveCriticalSection(&critical);
if (node==NULL) //Check condition to confirm
printf("node is null\n"); //that node has been deleted
else
printf("node is not null\n");
if (op==50) //op has been read from the node
{
//call function with detail as parameter...call is successful
free(detail);
Sleep(2000);
//Make some other function calls
op=-1;
if (node==NULL) //Another check condition to
printf("%d\n",op); //confirm that node is empty
else
printf("node is not null\n");
}
//some other similar conditions
}
DeleteCriticalSection(&critical);
//Close threads
return (0);
//End of main//Code for Linked List
struct fifo
{
int result;
char *info;
struct fifo *next;
}*node;
void add(struct fifo **n,int data,char *text)
{
struct fifo *temp,*node1;
if (*n==NULL)
{
temp=(struct fifo *)malloc(sizeof(struct fifo));
printf("%d is to be stored\n",data);
temp->result=data;
printf("%d is stored\n",temp->result);
temp->info=(char *)malloc(strlen(text)+1);
strcpy(temp->info,text);
temp->next=NULL;
*n=temp;
}
else
{
temp=*n;
while(temp->next!=NULL)
temp=temp->next;
node1=(struct fifo *)malloc(sizeof(struct fifo));
node1->result=data;
node1->info=(char *)malloc(strlen(text)+1);
strcpy(node1->info,text);
node1->next=NULL;
temp->next=node1;
}
}
void del(struct fifo **n)
{
struct fifo *temp;
if (*n==NULL)
{
printf("Linked list is empty\n");
}
else
{
temp=*n;
*n=temp->next;
}
}
//Code for Linked List ends
//Inside read thread that will add to the linked list
//If a particular condition is satisfied
EnterCriticalSection(&critical);
add(&node,50,location); //location holds string read
LeaveCriticalSection(&critical); //exit condition after this
//End of read thread
//Inside main thread that reads & deletes from the linked list
InitializeCriticalSection(&critical);
while(1)
{
if (node==NULL) //idle case
{
printf("Nothing to read\n");
Sleep(4000);
}
else //Linked List is not empty
{
EnterCriticalSection(&critical);
temp=(struct fifo *)malloc(sizeof(struct fifo)); //Read node
printf("%d\n%s\n",node->result,node->info);
op=node->result;
printf("op is %d\n",op);
detail=(char *) malloc (strlen(node->info));
strcpy(detail,node->info);
printf("%s\n",detail);
del(&node); //delete node
LeaveCriticalSection(&critical);
if (node==NULL) //Check condition to confirm
printf("node is null\n"); //that node has been deleted
else
printf("node is not null\n");
if (op==50) //op has been read from the node
{
//call function with detail as parameter...call is successful
free(detail);
Sleep(2000);
//Make some other function calls
op=-1;
if (node==NULL) //Another check condition to
printf("%d\n",op); //confirm that node is empty
else
printf("node is not null\n");
}
//some other similar conditions
}
DeleteCriticalSection(&critical);
//Close threads
return (0);
//End of main
Now here's the output:
Nothing to read
//after some time
50 //value of int stored in node
25 //string stored in node
op is 50
25
node is null
//results of function calls successfully printed
node is not null
Nothing to read
//after some time
50 //value of int stored in node
25 //string stored in node
op is 50
25
node is null
//results of function calls successfully printed
node is not null
As you can see from the output, 'main' first showed that the node is null, but after the function calls, it said that the node is not null. The function calls being made involve issuing commands to the port & reading their response(no entry is made to the linked list during this read).
I have noticed that I am getting the above output in situations when I have to read a very large string from the port. In such situations, the thread does not read the entire response in one attempt, but instead does so in multiple attempts. As a result, my linked list pointer somehow gets modified & hence it does not point to null anymore.
However, whenever the response has been small enough to be read in a single attempt, I have got no such error.
Can anybody please help me........
Here is my code:
//Code for Linked List
struct fifo
{
int result;
char *info;
struct fifo *next;
}*node;
void add(struct fifo **n,int data,char *text)
{
struct fifo *temp,*node1;
if (*n==NULL)
{
temp=(struct fifo *)malloc(sizeof(struct fifo));
printf("%d is to be stored\n",data);
temp->result=data;
printf("%d is stored\n",temp->result);
temp->info=(char *)malloc(strlen(text)+1);
strcpy(temp->info,text);
temp->next=NULL;
*n=temp;
}
else
{
temp=*n;
while(temp->next!=NULL)
temp=temp->next;
node1=(struct fifo *)malloc(sizeof(struct fifo));
node1->result=data;
node1->info=(char *)malloc(strlen(text)+1);
strcpy(node1->info,text);
node1->next=NULL;
temp->next=node1;
}
}
void del(struct fifo **n)
{
struct fifo *temp;
if (*n==NULL)
{
printf("Linked list is empty\n");
}
else
{
temp=*n;
*n=temp->next;
}
}
//Code for Linked List ends
//Inside read thread that will add to the linked list
//If a particular condition is satisfied
EnterCriticalSection(&critical);
add(&node,50,location); //location holds string read
LeaveCriticalSection(&critical); //exit condition after this
//End of read thread
//Inside main thread that reads & deletes from the linked list
InitializeCriticalSection(&critical);
while(1)
{
if (node==NULL) //idle case
{
printf("Nothing to read\n");
Sleep(4000);
}
else //Linked List is not empty
{
EnterCriticalSection(&critical);
temp=(struct fifo *)malloc(sizeof(struct fifo)); //Read node
printf("%d\n%s\n",node->result,node->info);
op=node->result;
printf("op is %d\n",op);
detail=(char *) malloc (strlen(node->info));
strcpy(detail,node->info);
printf("%s\n",detail);
del(&node); //delete node
LeaveCriticalSection(&critical);
if (node==NULL) //Check condition to confirm
printf("node is null\n"); //that node has been deleted
else
printf("node is not null\n");
if (op==50) //op has been read from the node
{
//call function with detail as parameter...call is successful
free(detail);
Sleep(2000);
//Make some other function calls
op=-1;
if (node==NULL) //Another check condition to
printf("%d\n",op); //confirm that node is empty
else
printf("node is not null\n");
}
//some other similar conditions
}
DeleteCriticalSection(&critical);
//Close threads
return (0);
//End of main//Code for Linked List
struct fifo
{
int result;
char *info;
struct fifo *next;
}*node;
void add(struct fifo **n,int data,char *text)
{
struct fifo *temp,*node1;
if (*n==NULL)
{
temp=(struct fifo *)malloc(sizeof(struct fifo));
printf("%d is to be stored\n",data);
temp->result=data;
printf("%d is stored\n",temp->result);
temp->info=(char *)malloc(strlen(text)+1);
strcpy(temp->info,text);
temp->next=NULL;
*n=temp;
}
else
{
temp=*n;
while(temp->next!=NULL)
temp=temp->next;
node1=(struct fifo *)malloc(sizeof(struct fifo));
node1->result=data;
node1->info=(char *)malloc(strlen(text)+1);
strcpy(node1->info,text);
node1->next=NULL;
temp->next=node1;
}
}
void del(struct fifo **n)
{
struct fifo *temp;
if (*n==NULL)
{
printf("Linked list is empty\n");
}
else
{
temp=*n;
*n=temp->next;
}
}
//Code for Linked List ends
//Inside read thread that will add to the linked list
//If a particular condition is satisfied
EnterCriticalSection(&critical);
add(&node,50,location); //location holds string read
LeaveCriticalSection(&critical); //exit condition after this
//End of read thread
//Inside main thread that reads & deletes from the linked list
InitializeCriticalSection(&critical);
while(1)
{
if (node==NULL) //idle case
{
printf("Nothing to read\n");
Sleep(4000);
}
else //Linked List is not empty
{
EnterCriticalSection(&critical);
temp=(struct fifo *)malloc(sizeof(struct fifo)); //Read node
printf("%d\n%s\n",node->result,node->info);
op=node->result;
printf("op is %d\n",op);
detail=(char *) malloc (strlen(node->info));
strcpy(detail,node->info);
printf("%s\n",detail);
del(&node); //delete node
LeaveCriticalSection(&critical);
if (node==NULL) //Check condition to confirm
printf("node is null\n"); //that node has been deleted
else
printf("node is not null\n");
if (op==50) //op has been read from the node
{
//call function with detail as parameter...call is successful
free(detail);
Sleep(2000);
//Make some other function calls
op=-1;
if (node==NULL) //Another check condition to
printf("%d\n",op); //confirm that node is empty
else
printf("node is not null\n");
}
//some other similar conditions
}
DeleteCriticalSection(&critical);
//Close threads
return (0);
//End of main
Now here's the output:
Nothing to read
//after some time
50 //value of int stored in node
25 //string stored in node
op is 50
25
node is null
//results of function calls successfully printed
node is not null
Nothing to read
//after some time
50 //value of int stored in node
25 //string stored in node
op is 50
25
node is null
//results of function calls successfully printed
node is not null
As you can see from the output, 'main' first showed that the node is null, but after the function calls, it said that the node is not null. The function calls being made involve issuing commands to the port & reading their response(no entry is made to the linked list during this read).
I have noticed that I am getting the above output in situations when I have to read a very large string from the port. In such situations, the thread does not read the entire response in one attempt, but instead does so in multiple attempts. As a result, my linked list pointer somehow gets modified & hence it does not point to null anymore.
However, whenever the response has been small enough to be read in a single attempt, I have got no such error.
Can anybody please help me........