Author : LUPG
Page : << Previous 15
* input.
* perform an endless loop of reading user input. If user
* pressed 'e', signal our condition variable and end the thread.
* input: none.
* output: none.
*/
void*
read_user_input(void* data)
{
int c;
/* register cleanup handler */
pthread_cleanup_push(restore_coocked_mode, NULL);
/* make sure we're in asynchronous cancelation mode so */
/* we can be canceled even when blocked on reading data. */
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
/* put screen in raw data mode */
system("stty raw -echo");
/* "endless" loop - read data from the user. */
/* terminate the loop if we got a 'e', or are canceled. */
while ((c = getchar()) != EOF) {
if (c == 'e') {
#ifdef DEBUG
printf("\n\ngot a 'e'\n\n\r");
fflush(stdout);
#endif /* DEBUG */
/* mark that there was a cancel request by the user */
cancel_operation = 1;
/* signify that we are done */
pthread_cond_signal(&action_cond);
pthread_exit(NULL);
}
}
/* pop cleanup handler, while executing it, to restore cooked mode. */
pthread_cleanup_pop(1);
}
/*
* function: file_line_count - counts the number of lines in the given file.
* algorithm: open the data file, read it character by character, and count
* all newline characters.
* input: file name.
* output: number of lines in the given file.
*/
void*
file_line_count(void* data)
{
char* data_file = (char*)data;
FILE* f = fopen(data_file, "r");
int wc = 0;
int c;
if (!f) {
perror("fopen");
exit(1);
}
/* make sure we're in asynchronous cancelation mode so */
/* we can be canceled even when blocked on reading data. */
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
while ((c = getc(f)) != EOF) {
if (c == '\n')
wc++;
}
fclose(f);
/* signify that we are done. */
pthread_cond_signal(&action_cond);
return (void*)wc;
}
/* like any C program, program's execution begins in main */
int
main(int argc, char* argv[])
{
pthread_t thread_line_count; /* 'handle' of line-counting thread. */
pthread_t thread_user_input; /* 'handle' of user-input thread. */
void* line_count; /* return value from line-counting thread. */
printf("Checking file size (press 'e' to cancel operation)...");
fflush(stdout);
/* spawn the line counting thread */
pthread_create(&thread_line_count,
NULL,
file_line_count,
(void*)DATA_FILE);
/* spawn the user-reading thread */
pthread_create(&thread_user_input,
NULL,
read_user_input,
(void*)DATA_FILE);
/* lock the mutex, and wait on the condition variable, */
/* till one of the threads finishes up and signals it. */
pthread_mutex_lock(&action_mutex);
pthread_cond_wait(&action_cond, &action_mutex);
pthread_mutex_unlock(&action_mutex);
#ifdef DEBUG
printf("\n\rmain: we got signaled\n\n\r");
fflush(stdout);
#endif /* DEBUG */
/* check if we were signaled due to user operation */
/* cancelling, or because the line-counting was finished. */
if (cancel_operation) {
/* we join it to make sure it restores normal */
/* screen mode before we print out. */
pthread_join(thread_user_input, NULL);
printf("operation canceled\n");
fflush(stdout);
/* cancel the file-checking thread */
pthread_cancel(thread_line_count);
}
else {
/* join the file line-counting thread, to get its results */
pthread_join(thread_line_count, &line_count);
/* cancel and join the user-input thread. */
/* we join it to make sure it restores normal */
/* screen mode before we print out. */
pthread_cancel(thread_user_input);
pthread_join(thread_user_input, NULL);
/* and print the result */
printf("'%d' lines.\n", (int)line_count);
}
return 0;
}
Page : << Previous 15