Issue: I created a linked list of Child thread TIDS and want to wait on all the child tids to finish execution before I continue my main thread. Basically I have directory traversal (a directory is specified by the members of a given struct
). Every time I see a directory or file I create a new thread and put its threadID
into the linked list. However when I traverse the linked list and call pthread_join
I get a segmentation fault (core dumped) - I cannot understand why. I believe in may have to do with race condition but I am not sure. When I remove the pthread_join
I no longer segfault however I don't get full traversal of directories within directories.
Program:
void *handy(void *arguments)
{
static pthread_t threadA;
threadA=pthread_self();
handarg *thestruct=(handarg*)arguments;
DIR *dp=opendir(thestruct->directory);
DIR *outExist=opendir(thestruct->outputdirectory);
if(outExist==NULL)
{
if((thestruct->outputdirectory = ""))
{
;
}
else
{
printf("The outputdirectory doesnt exist, program terminated\n");
exit(1);
}
}
struct dirent *entry; // has two important members (d-type)-tells me if its a directory (d-name) tells me current file name
if(dp==NULL)
{
printf("directory doesnt exist: %s\n", thestruct->directory);
exit(1);
}
NODE *head=NULL; //linked list
NODE *ptr=(NODE*)malloc(sizeof(NODE));//node POINTER
int count;
while((entry=readdir(dp))!=NULL)
{
if(strcmp(entry->d_name,"..")==0||strcmp(entry->d_name,".")==0)
{
continue;
}
if((entry->d_type==DT_DIR))
{
unsigned int const sz1 = strlen(thestruct->directory);
unsigned int const sz2 = strlen(entry->d_name);
char *dnewname=(char *)malloc((sz1+sz2+2)*sizeof(char));
memcpy(dnewname,thestruct->directory,sz1);
memcpy(dnewname+sz1,"/",sizeof(char));
memcpy(dnewname+sz1+1,entry->d_name,sz2);
dnewname[strlen(dnewname)]='\0';
pthread_t tid;
handarg *current=(handarg*)malloc(sizeof(handarg));//malloc
current->directory=dnewname;
current->outputdirectory=thestruct->outputdirectory;
current->column=thestruct->column;
pthread_create(&tid,NULL,&handy,current);
threadA=pthread_self();
printf("The Filepath is: %s, The Parent TID = %ld, THE peer TID = %ld\n",dnewname, threadA, tid);
NODE *newNode=(NODE*)malloc(sizeof(NODE));
newNode->peerTid=tid;
newNode->next=NULL;
if(head==NULL)
{
head=newNode;
ptr=newNode;
//printf("THE TID I PUT INTO THIS NODE IS FUCK YOU FUCK YOU FUCK YOU %ld\n",ptr->peerTid);
}
else
{
ptr->next=newNode;
ptr=newNode;
//printf("THE TID I PUT INTO THIS NODE IS YAMAKA %ld\n",ptr->peerTid);
}
//and call wait on each of tids for loop only exit if last tid is waiting on
}
if((entry->d_type==DT_REG))
{
char *filename = entry->d_name;
int len = strlen(filename);
const char *last_four = &filename[len-4]; //need to account for if filename is less than 4 characters
if(strcmp(last_four,".csv")==0)
{
char *dnewname = (char*)malloc(sizeof(char)*(strlen(thestruct->directory)+strlen(entry->d_name)+2));
char *slash = (char*)malloc(sizeof(char));
strcpy(dnewname, thestruct->directory);
strcpy(slash, "/");
strcat(dnewname, slash);
strcat(dnewname, entry->d_name);
dnewname[strlen(dnewname)]='\0';
pthread_t tid;
handarg *current=(handarg*)malloc(sizeof(handarg));
current->directory=dnewname;
current->outputdirectory=thestruct->outputdirectory;
current->column=thestruct->column;
pthread_create(&tid,NULL,&handleFile,current);
//count++;
threadA=pthread_self();
printf("The Filepath is: %s, The Parent TID = %ld, THE peer TID = %ld\n",dnewname, threadA, tid);
NODE *newNode=(NODE*)malloc(sizeof(NODE));
newNode->peerTid=tid;
newNode->next=NULL;
if(head==NULL)
{
head=newNode;
ptr=newNode;
//printf("THE TID I PUT INTO THIS NODE IS %ld\n",ptr->peerTid);
}
else
{
ptr->next=newNode;
ptr=newNode;
//printf("THE TID I PUT INTO THIS NODE IS %ld\n",ptr->peerTid);
}
}
}
}
printf("the thread produced %d threads\n", count);
if(head==NULL)
{
printf("no child threads\n");
}
ptr=head;
printf("\nthese are the items from the linkedlist\n\n");
while (ptr!=NULL)
{
printf("%ld\n",ptr->peerTid);
ptr=ptr->next;
}
printf("\n");
ptr=head;
while (ptr!=NULL)
{
threadA=pthread_self();
printf("THE PEER THREAD %ld --------I AM THE THREAD %ld\n",ptr->peerTid,threadA);
pthread_join(ptr->peerTid,NULL);
printf("got here");
ptr=ptr->next;
}
printf("\n");
//return NULL;
}