Note that there are some explanatory texts on larger screens.

plurals
  1. PODebug recursive thread call in C
    primarykey
    data
    text
    <p>I have been trying to debug my code whenever I had free-time for the past day and a half and I don't know what is wrong with my code. When I add the <code>close()</code> function to a recursive call, the program gives me an invalid pointer. But when I remove the <code>close()</code> function call the program runs fine, except it does not do what it is supposed to do, which is:</p> <ul> <li>add up all the file sizes in a user input directory</li> <li>open sub-directories, if any, and add up all the files inside the sub-directory</li> </ul> <p>Instead, it adds up all the file sizes in the input directory and is able to open the last sub-directory and add the files within that directory to the total file size count.</p> <p>I am trying to do this with threads. The <code>main()</code> function creates one main thread from the user input directory and runs <code>opendirectory()</code> off the bat.</p> <pre><code>/* * Iterates through given directory */ void *opendirectory(void *t) { pthread_mutex_lock(&amp;dirlock); DIR *dpntr; struct dirent *dentry; char new_directory[512], dir = t; printf("OPENING DIRECTORY ... %s\n", t); /* Checks if given directory can be opened */ if((dpntr = opendir(t)) == NULL) { printf("DIRECTORY FAILED ...%s\n",t); perror("ERROR -- COULD NOT OPEN DIR"); pthread_exit(NULL); } printf("DIRECTORY OPENED: %s\n", t); /* Read each file in current directory */ while ((dentry = readdir(dpntr)) != NULL ) { /* Ignore special directories */ if(strcmp(dentry -&gt; d_name, ".") == 0 || strcmp(dentry -&gt; d_name, "..") == 0) { continue; } else { compilelist( t, dentry-&gt;d_name ); } } pthread_mutex_unlock(&amp;dirlock); /* Checks if directory can be closed */ if(closedir(dpntr) &lt; 0) printf("ERROR CLOSING %s.\n", t); } </code></pre> <p>This is the function that will determine if a new thread should be created and is supposed to run recursively.</p> <pre><code>/* * Determines if current file is a directory * Creates a new thread if true */ void compilelist (const char* dirname, const char *filename) { pthread_mutex_lock(&amp;filelock); struct stat statdata; char *filepathname, *dpntr; /* Allocate memory for filepathname */ if((filepathname = (char *) malloc(sizeof(char) * strlen(dirname))) == NULL) { printf("CANNOT ALLOCATE MEMORY FOR FILE PATH NAME."); pthread_exit(NULL); } /* Concats directory name with file name */ if(dirname[strlen(dirname) -1] == '/') { pthread_mutex_lock(&amp;pathlock); sprintf(filepathname, "%s%s", dirname, filename); pthread_mutex_unlock(&amp;pathlock); }else { pthread_mutex_lock(&amp;pathlock); sprintf(filepathname, "%s/%s", dirname, filename); pthread_mutex_unlock(&amp;pathlock); } lstat(filepathname, &amp;statdata); /* Calls print_statdata() if current item is a file */ if(!(S_ISDIR(statdata.st_mode))) { printf("FILE: %s\n", filepathname); if(!stat( filepathname, &amp;statdata)) { print_statdata( filename, &amp;statdata ); } else { fprintf (stderr, "GETTING STAT FOR %s", filepathname); perror( "ERROR IN STATDATA WHILE GETTING STAT"); } } /* Recursive call to opendirectory() */ else { pthread_mutex_lock(&amp;dircountlock); dirCount++; pthread_mutex_unlock(&amp;dircountlock); dpntr = filepathname; free(filepathname); printf("SUB-DIRECTORY THREAD: %s\nTHREAD ID NUMBER: %d\n", dpntr, dirCount); pthread_attr_setdetachstate(&amp;attr, PTHREAD_CREATE_JOINABLE); pthread_create(&amp;threads[dirCount-1], &amp;attr, opendirectory, (void *)dpntr); } pthread_mutex_unlock(&amp;filelock); } </code></pre> <p>Here is the <code>main()</code></p> <pre><code>/* * Main function prompts user for a directory */ int main(int argc, char *argv[]) { int i; char *dPtr; // pthread_attr_t attr; printf("ENTER A DIRECTORY:\n\t"); scanf("%s", directory); dPtr = directory; /* Initialize mutex and condition variable objects */ pthread_mutex_init(&amp;mutex, NULL); pthread_mutex_init(&amp;filelock, NULL); pthread_mutex_init(&amp;dirlock, NULL); pthread_mutex_init(&amp;dircountlock, NULL); pthread_cond_init (&amp;count_threshold_cv, NULL); /* For portability, explicitly create threads in a joinable state */ pthread_attr_init(&amp;attr); pthread_attr_setdetachstate(&amp;attr, PTHREAD_CREATE_JOINABLE); pthread_create(&amp;threads[0], &amp;attr, opendirectory, (void *)dPtr); /* Wait for all threads to complete */ for (i = 0; i &lt; dirCount; i++) { pthread_join(threads[i], NULL); } printf("TOTAL DIRECTORY SIZE: %d\n", dirSize); /* Clean up and exit */ pthread_attr_destroy(&amp;attr); pthread_mutex_destroy(&amp;mutex); pthread_mutex_destroy(&amp;filelock); pthread_mutex_destroy(&amp;dirlock); pthread_mutex_destroy(&amp;dircountlock); pthread_cond_destroy(&amp;count_threshold_cv); pthread_exit (NULL); } </code></pre> <p>And the global variables ...</p> <pre><code>pthread_mutex_t mutex; pthread_mutex_t dirlock; pthread_mutex_t filelock; pthread_mutex_t dircountlock; pthread_mutex_t threadlock; pthread_cond_t count_threshold_cv; pthread_attr_t attr; pthread_t threads[128]; // handles up to 128 threads (i.e. 128 directories, change accordingly) char directory[512]; int dirSize = 0; int dirCount = 1; // user's input directory </code></pre> <p>I feel that the <code>pthread_create()</code> called at the bottom of the <code>compilelist()</code> function is not working properly. The threads[] refers to a global array of threads that has a default size of 20, assuming that there will be no more than 20 total directories. dirCount starts off at 1 because of the user's input directory and increases as new directories are encountered.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload