The goal of this assignment is to implement an event loop and a stream abstraction.
An Event Loop maintains a FIFO queue of function/argument pairs. Events are identified by strings. Handler functions can be registered for particular events. When an event occurs, it is announced along with an argument to be passed to its handler. If a handler is registered for the event, its handler and the announced argument are placed on the end of the queue. A Event Loop is single-threaded, repeatedly dequeuing the function/argument pair at the front of the queue, and executing them. If the queue is empty, the Event Loop blocks until an event is announced.
The mandatory interface (set of public functions) for Event Loops is defined in ~cs520/public/prog6/EventLoop.h. (Do not change this file!) The documentation in this file specifies more details about the behavior of Event Loops, so be sure to read it carefully. Put your implementation of these functions in EventLoop.c.
For full credit, an Event Loop should be capable of accepting event registrations and event announcements from a different thread.
A Stream generates a stream of values and is designed to work with an Event Loop. Streams are executed in a separate thread. When creating a Stream, an "initialize" function and a "produce" function must be provided, as well as names (strings) for the "data" event and the "end" event. In addition, an active Event Loop must be provided. When the Stream is started, it first calls the "initialize" function, then it starts a thread to repeatedly call the "produce" function. When the "produce" function returns, a "data" event is announced to the Event Loop, with the return value of the "produce" function being provided as the argument for the data event handler. When the "produce" function indicates there are no more values, then an "end" event is announced to the Event Loop.
The mandatory interface (set of public functions) for Streams is defined in ~cs520/public/prog6/Stream.h. (Do not change this file!) The documentation in this file specifies more details about the behavior of Streams, so be sure to read it carefully. Put your implementation of these functions in Stream.c.
Use your implementation of Streams and Event Loops to write a program to read a file in blocks and count the number of newlines in the file. That is, create a Stream in which the "initialize" function will be passed a filename. It will open the file and then each call to the "produce" function will read the next 1000 bytes from the file, returning a pointer to the block. The handler for the "data" event should then scan the block, counting the number of newlines in the block, and adding it to a global sum for the file. At EOF, the "produce" function should indicate that the Stream is done. (And, of course, the last block read from the file will probably be less than 1000 bytes long, so the block length as the well as the pointer to the block needs to be provided to the "data" event handler. That is, you will need to allocate a struct to contain both the buffer and its length, and return the pointer to this struct from the "produce" function.) The handler for the "end" event should print the final count for the file. Put this code in readFile.c. This file should contain a "main" function, which accepts one argument, the file to be read. If this argument is not given, or more than one filename argument is provided, or the given filename cannot be opened, print an error message and terminate the program. Be sure your code properly allocates and deallocates all memory. Use valgrind to confirm this.
In ~cs520/public/prog6/syncMain.c is a simple test of an Event Loop that does not require the Event Loop to support interaction with a separate thread.
In ~cs520/public/prog6/streamPi.c is a simple test of a Stream that uses numeric integration to compute Pi.
Your program will be graded primarily by testing it for correct functionality:
Please turn-off any debugging code before you submit your program.
Your programs will be graded using agate.cs.unh.edu so be sure to test in that environment.
Your programs should be submitted for grading from
agate.cs.unh.edu.
To turn in this assignment, type:
~cs520/bin/submit prog6 EventLoop.c Stream.c readFile.c
Submissions can be checked by typing:
~cs520/bin/scheck prog6
To receive full credit for the assignment, you must turn in your files prior to 8am on Thursday April 24. The standard policy concerning late submissions will be in effect. See the course overview webpage.
Remember: as always you are expected to do your own work on this assignment.
Comments and questions should be directed to hatcher@unh.edu