The event driven programming style

cnet employs an event-driven style of programming similar, though not identical, to the data-link layer protocols presented in Tanenbaum [Prentice-Hall,1988]. Execution proceeds when cnet informs protocols that an event of interest has occurred. Protocols are expected to respond to these events.

Events occur when a node reboots, the Application Layer has a message for delivery, the Physical Layer receives a frame on a link, a timer event expires, a debugging button (under X-windows) is selected, and a node is (politely) shutdown (no event is delivered if a node pauses, crashes or suffers a hardware failure). These last few events only occur in simulations designed to address the highest layers of the OSI model.

Event-handling functions must be registered to receive incoming events. The only exception to this is that the function reboot_node() is assumed to be the function to invoke on node reboots (unless overridden with either the -R option or the rebootnode attribute). Each handler is invoked with three parameters - the event causing the invocation, a timer and a user-defined data value.

Each node is initially rebooted by calling the supplied function reboot_node (this is the only function that you must provide). reboot_node is an example of an event-handling function. All such functions are called by cnet with three parameters, the first is the type of event (one of the CnetEvent enumerated values), the second is a unique timer (described later) and the third, some user-specified data (typically 0 and ignored). The purpose of calling reboot_node is to give protocols chance to allocate any necessary dynamic memory, initialize variables, inform cnet in which events protocols are interested, and which functions cnet should call when these events occur.

Consider the following protocol skeleton. Like all cnet protocol files, the standard cnet header file is first included. This contains all definitions and function prototypes necessary for protocols. Here the reboot_node function informs cnet that when the Application Layer has a message for delivery to another host (because EV_APPLICATIONREADY occurs) cnet should call the function appl_ready which, presumably, will read the new message from the Application Layer and thus commence the delivery process.


#include <cnet.h>

void appl_ready(CnetEvent ev, CnetTimer ts, CnetData data)
{
  ...
  result = CNET_read_application( ... );
  ...
}

void reboot_node(CnetEvent ev, CnetTimer ts, CnetData data)
{
  ...
  result = CNET_set_handler(EV_APPLICATIONREADY, appl_ready, 0);
  ...
}

The user-defined data value is initially provided as the third parameter to CNET_set_handler which will ensure that the same data value is passed to the handler. The user-defined data value for timeout handlers is also presented as the third parameter to CNET_start_timer.


Timers

cnet supports 10 timer event queues providing a call-back mechanism for the protocol code. For example, the event EV_TIMER1 may be requested to be ``raised'' in 5000ms, and cnet will call the EV_TIMER1 event-handler in 5 seconds time. Timers are referenced via unique values. For example:

timer1 = CNET_start_timer(EV_TIMER1, 5000, 0);

The timer has significance for functions handling timer events; all other handlers will simply receive the special NULLTIMER. Notice that timers do not reflect the current time; they specify which timer has expired. When a timer expires, the event-handler for the corresponding event is invoked with the event and the unique timer as parameters. Timers may be cancelled prematurely with CNET_stop_timer to prevent them expiring, for example:


    (void)CNET_stop_timer(timer1);

though they are automatically cancelled as a result of their handler being invoked.

IMPORTANT:
Event-handling functions must execute to their completion - they must perform their actions and then simply return. cnet does not employ pre-emptive scheduling - once an event handling function is being executed, it will not be interrupted by the arrival of another event. Event-handling functions are of type void - that is, they do not return a value. If event-handling functions do not return, the whole simulation, including all windowing, will block and cnet must be interrupted via the invoking xterm.


cnet was written and is maintained by Chris McDonald (chris@cs.uwa.edu.au)