©2004 by Marc J. Rochkind. All rights reserved. Portions marked "Open Source" may be copied under license.

 

Main Page   Modules   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

c5/t2-mtx.c

Go to the documentation of this file.
00001 /*
00002     Thread example (background sorting; with mutexes)
00003     AUP2, Sec. 5.17 (not in book)
00004 
00005     Copyright 2003 by Marc J. Rochkind. All rights reserved.
00006     May be copied only for purposes and under conditions described
00007     on the Web page www.basepath.com/aup/copyright.htm.
00008 
00009     The Example Files are provided "as is," without any warranty;
00010     without even the implied warranty of merchantability or fitness
00011     for a particular purpose. The author and his publisher are not
00012     responsible for any damages, direct or incidental, resulting
00013     from the use or non-use of these Example Files.
00014 
00015     The Example Files may contain defects, and some contain deliberate
00016     coding mistakes that were included for educational reasons.
00017     You are responsible for determining if and how the Example Files
00018     are to be used.
00019 
00020 */
00021 #include "defs.h"
00022 #include <pthread.h>
00023 
00024 #define MAX_ENTRIES 100
00025 
00026 struct dict {
00027     int d_nentries;
00028     char *d_entry[MAX_ENTRIES];
00029     bool d_issorted;
00030 };
00031 
00032 static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
00033 
00034 static int compar(const void *x, const void *y)
00035 {
00036     return strcmp(*(char **)x, *(char **)y);
00037 }
00038 
00039 static void *sorter(void *arg)
00040 {
00041     struct dict *d = arg;
00042 
00043     while (true) {
00044         ec_rv( pthread_mutex_lock(&mtx) )
00045         if (!d->d_issorted) {
00046             qsort(d->d_entry, d->d_nentries, sizeof(char *), compar);
00047             d->d_issorted = true;
00048         }
00049         ec_rv( pthread_mutex_unlock(&mtx) )
00050         sleep(1);
00051     }
00052 
00053 EC_CLEANUP_BGN
00054     exit(EXIT_FAILURE);
00055 EC_CLEANUP_END
00056 }
00057 
00058 int main(void)
00059 {
00060     struct dict dictionary;
00061     pthread_t tid;
00062     char word[100];
00063     int i;
00064     size_t wordlen;
00065 
00066     dictionary.d_nentries = 0;
00067     dictionary.d_issorted = true;
00068     ec_rv( pthread_create(&tid, NULL, sorter, &dictionary) )
00069     while (true) {
00070         printf("Word? ");
00071         if (fgets(word, sizeof(word), stdin) == NULL && ferror(stdin))
00072             EC_FAIL
00073         if (feof(stdin))
00074             break;
00075         if (word[0] == '-') {
00076             ec_rv( pthread_mutex_lock(&mtx) )
00077             if (dictionary.d_issorted)
00078                 for (i = 0; i < dictionary.d_nentries; i++)
00079                     printf("\t%s\n", dictionary.d_entry[i]);
00080             else
00081                 printf("Not sorted -- try again later\n");
00082             ec_rv( pthread_mutex_unlock(&mtx) )
00083             continue;
00084         }
00085         wordlen = strlen(word);
00086         if (word[wordlen - 1] == '\n')
00087             word[--wordlen] = '\0';
00088         if (dictionary.d_nentries >= MAX_ENTRIES) {
00089             errno = E2BIG;
00090             EC_FAIL
00091         }
00092         ec_null( dictionary.d_entry[dictionary.d_nentries] =
00093           malloc(wordlen + 1) )
00094         strcpy(dictionary.d_entry[dictionary.d_nentries], word);
00095         ec_rv( pthread_mutex_lock(&mtx) )
00096         dictionary.d_nentries++;
00097         dictionary.d_issorted = false;
00098         ec_rv( pthread_mutex_unlock(&mtx) )
00099     }
00100     printf("Done\n");
00101     return EXIT_SUCCESS;
00102 
00103 EC_CLEANUP_BGN
00104     return EXIT_FAILURE;
00105 EC_CLEANUP_END
00106 }

Generated on Fri Apr 23 10:56:57 2004 for AUP2 Example Source by doxygen 1.3.1