PreviousNext

Using An ET System

In the previous chapter, we learned how to create an ET system, and in this chapter we'll learn to use an existing system. This chapter shows how users can attach to ET systems, define, create and remove stations, attach to and detach from stations, handle events, and handle signals.

Opening an ET System

Opening a system is done by calling et_open (et_sys_id* id, char *filename,et_openconfig config). The user defines a variable of type et_sys_id and passes its pointer - a value-result argument - which then gives back an "ID" to the open ET system. In addition, the filename of an existing ET system and a parameter describing how the user would like to open the system are passed as parameters to et_open.

There are a number of functions used to create and define the config argument. It is initialized by a call to et_open_config_init (et_openconfig *config). When the user is finished using the configuration, et_open_config_destroy (et_openconfig config) must be called in order to properly release all memory used.

After initialization, calls can be made to functions which set various properties of the specific configuration. Calls to these setting functions will fail unless the configuration is first initialized. The functions used to SET these properties are listed below along with an explanation for each:

1.      et_open_config_setwait(et_openconfig config, int val) : setting val to ET_OPEN_WAIT makes et_open block by waiting until the given ET system is fully functioning or a set time period has passed before returning. Setting val to ET_OPEN_NOWAIT make et_open return immediately after determining whether the ET system is alive or not. If the system is remote, then broadcasting to find its location may take up to several seconds. The default is ET_OPEN_NOWAIT.

2.      et_open_config_settimeout(et_openconfig config, struct timespec val) : in ET_OPEN_WAIT mode, this function sets the maximum amount of time to wait for an alive ET system to appear. If the time is set to zero (the default), an infinite time is indicated. If broad/multicasting to find a remote ET system, it is possible to take up to several seconds to determine whether the system is alive or not -- possibly exceeding the time limit.

3.      et_open_config_sethost(et_openconfig config, char *val) : this sets the name of the host (computer) on which the ET system resides. For opening a local system only, set val to ET_HOST_LOCAL (the default) or "localhost" (including quotes). For opening a system on an unknown host, set it to ET_HOST_REMOTE. For an unknown host which may be local or remote, set it to ET_HOST_ANYWHERE. Otherwise set val to the name or dotted-decimal IP address of the desired host. (See next routine also).

4.      et_open_config_setcast(et_openconfig config, int val) : setting val to ET_BROADCAST (default) means using UDP broadcast IP packets to determine the location of ET systems so they can be opened. Setting val to ET_MULTICAST uses the newer UDP multicast IP packets to do the same. Setting val to ET_BROADANDMULTICAST does both. However setting val to ET_DIRECT makes a direct connection to the ET system and requires that et_open_config_sethost use the actual host's name, "localhost" or ET_HOST_LOCAL and not ET_HOST_REMOTE or ET_HOST_ANYWHERE. The TCP port number used in the direct connection is set by et_open_config_setserverport and defaults to ET_SERVER_PORT, defined in et.h as 11111.

5.      et_open_config_setTTL(et_openconfig config, int val) : when using multicasting, set the TTL value. This sets the number of routers to hop. The default is 32 which should allow multicast packets to pass through the local network routers.

6.      et_open_config_setport(et_openconfig config, unsigned short val) : this sets the port number of the UDP broadcast communications. The default is ET_BROADCAST_PORT, defined in et.h as 11111.

7.      et_open_config_setmultiport(et_openconfig config, unsigned short val) : this sets the port number of the UDP multicast communications. The default is ET_MULTICAST_PORT, defined in et.h as 11111. It will be necessary to use this routine when opening a Java-based ET system as broadcast and multicast ports must be different.

8.      et_open_config_setserverport(et_openconfig config, unsigned short val) : this sets the port number of the TCP server thread of an ET system. The default is ET_SERVER_PORT, defined in et.h as 11111.

9.      et_open_config_addbroadcast(et_openconfig config, char *val) : this adds an IP subnet broadcast address to a list of destinations used in broadcast discovery of the ET system to be opened. The val argument may also be set to ET_SUBNET_ALL which specifies all the local subnet broadcast addresses. Format is dotted-decimal only. Broadcasting is only used if et_open_config_setcast is set to ET_BROADCAST or ET_BROADANDMULTICAST.

10.  et_open_config_removebroadcast(et_openconfig config, char *val) : this removes an IP subnet broadcast address from a list of destinations used in broadcast discovery of the ET system to be opened. If there is no such address on the list, it is ignored. The val argument may also be set to ET_SUBNET_ALL which removes all the subnet broadcast addresses (empties the list). Dotted-decimal only.

11.  et_open_config_addmulticast(et_openconfig config, char *val) : this adds a multicast address to a list of destinations used in multicast discovery of the ET system to be opened. There can be at most ET_MAXADDRESSES (defined in et_private.h as 10) addresses on the list. Duplicate entries are not added to the list. Format is dotted-decimal. Multicasting is only used if et_open_config_setcast is set to ET_MULTICAST or ET_BROADANDMULTICAST.

12.  et_open_config_removemulticast(et_openconfig config, char *val) :  this removes a multicast address from a list of destinations used in multicast discovery of the ET system to be opened. If there is no such address on the list, it is ignored. Dotted-decimal.

13.  et_open_config_setpolicy(et_openconfig config, int val) : this sets the return policy from an et_open call so that if et_open generates more than one response from one or more ET systems, different things can be done. Setting val to ET_POLICY_ERROR returns an error, ET_POLICY_FIRST opens the first responding system, and ET_POLICY_LOCAL opens the first responding local system if there is one, and if not, the first responding system.

14.  et_open_config_setmode(et_openconfig config, int val) : setting val to ET_HOST_AS_LOCAL (default) means users which are on the same machine as the ET system (local) will realize this and take advantage of it. However, setting val to ET_HOST_AS_REMOTE means users will be treated as if they were remote even if they are local. All transactions will be through the ET system's server and not through shared memory.

15.  et_open_config_setdebugdefault(et_openconfig config, int val) : this sets the default level of debugging output. Set val to: ET_DEBUG_NONE for no output, ET_DEBUG_SEVERE for output describing severe errors, ET_DEBUG_ERROR for output describing all errors, ET_DEBUG_WARN for output describing warnings and errors, and ET_DEBUG_INFO for output describing all information, warnings, and errors.

16.  et_open_config_setinterface(et_openconfig config, int val) : this sets the network interface to use in order to communicate with the ET system (if not local and mode is not ET_HOST_AS_REMOTE). Set val to the dotted decimal form of the IP address of the interface desired.

17.  et_open_config_settcp(et_openconfig config, int  rBufSize, int sBufSize, int noDelay) : regarding the TCP connection to the ET system, this sets the TCP receive buffer size in bytes, the TCP send buffer size in bytes, and sets the TCP “no delay” on or off. If either buffer size is zero, then system default values are used. A value of 0 turns off the “no delay” and any other value turns it on.

More on remote ET systems can be found in the chapter entitled Remote ET. All of the above "set" functions have their counterpart "get" functions as well.

Once an ET system has been opened, users can use the id as a handle for that particular system. Users can open more than one system at a time, referring to each by their respective handles.

What are Stations?

Stations are places in shared memory containing 2 lists of events – the input and output lists. Users can grab events from the input list for processing and when put back to the ET system, those events go to the station’s output list. From the output list, the station’s conductor thread will move the events to other stations further down the line. In the following diagram, the arrows represent the conductor threads. GRAND_CENTRAL is the first station, exists in all ET systems, and its input list contains all the unused events. Users usually grab unused events from this station, put their data into them, and put them back. In this way all stations further down the line will eventually get a chance to process them.

 

 

Stations can be blocking or non-blocking. Blocking stations receive all events from the previous station(s) and its input and output lists (or queues) are large enough to contain all events of the ET system. Non-blocking stations, on the other hand, have settable input queue sizes. Once the input queue is full, all other events flowing through the system will bypass the station and go to the next one in line. Setting the queue size large enough to contain all events will have the effect of making non-blocking stations behave as those that block.

Stations normally exist in a serial flow of events – that is, the user puts events back into a station, the events flow to the next in a serial line of stations until they eventually reach GRAND_CENTRAL where they are reused. However, stations can be grouped together to act as a unit when all stations in the unit are declared to have parallel event flow. In the diagram below, P1, P2, and P3 are parallel stations with P1 being the head. In addition to normal distribution methods, S1’s conductor can distribute its events to the parallel stations with 2 special algorithms. One is a round robin algorithm (which is self-explanatory) and the other is an equal-queue algorithm in which the conductor tries to keep the input queues of P1, P2, & P3 equally full for load balancing. When events are put back into a parallel station, its conductor will place them into the next appropriate serial or head parallel station.

 

 

 

Definition of Stations

Definition

Analogous to the opening or creation of ET systems, users begin by declaring a variable of type et_statconfig. Once this variable is declared, it must be initialized before further use. Thus users must also call the function et_station_config_init(et_statconfig* sconfig). After initialization, calls can be made to functions which set various properties of the specific configuration. Calls to these setting functions will fail unless the configuration is first initialized.

When the user is finished using a configuration variable, the user must call et_station_config_destroy(et_statconfig sconfig) with the configuration as an argument in order to properly release all memory used.

The functions used to SET station parameters are listed below along with an explanation for each:

1.      et_station_config_setblock(et_statconfig sconfig, int val) : setting val to ET_STATION_BLOCKING makes the station block by looking at all events in the system, while setting it to ET_STATION_NONBLOCKING allows the station to fill up a cue of events and when that is full, events flow to the next station downstream. The default is blocking.

2.      et_station_config_setflow(et_statconfig sconfig, int val) setting val to ET_STATION_SERIAL makes events flow through the station normally, while setting it to ET_STATION_PARALLEL can make the station part of a group of stations through which events flow in parallel downstream. The default is serial.

3.      et_station_config_setcue(et_statconfig sconfig, int val) : when in non-blocking mode, this sets the maximum number of events that are to be in the station's input list ready for reading (in so far as it is possible). The default is 10.

4.      et_station_config_setprescale(et_statconfig sconfig, int val) : when in blocking mode, every Nth event of interest is sent to the user by setting the val to N. The default is 1.

5.      et_station_config_setuser(et_statconfig sconfig, int val) : setting val to ET_STATION_USER_SINGLE allows only one user process to attach to this station, while setting it to ET_STATION_USER_MULTI allows multiple users to attach. Setting it to a positive integer allows only that number of attachments to the station. The default is multiuser.

6.      et_station_config_setrestore(et_statconfig sconfig, int val) : when a process dies or detaches from a station, the events it read but did not write are recovered and sent to a station's output list if val is set to ET_STATION_RESTORE_OUT. Similarly, they can be sent to the input list with ET_STATION_RESTORE_IN or back to GRAND_CENTRAL station with ET_STATION_RESTORE_GC. Finally, if val is ET_STATION_RESTORE_REDIST and if the station has parallel flow, the events can be sent to the output list of the previous station in which case these events will be redistributed to the group of parallel stations. This final option is useful, for example, in a processing farm of parallel stations. If a farm node (and its accompanying attachments) disappears, all the events that were written to it can be automatically redistributed to other farm nodes. The default is restoration to the output list.

7.      et_station_config_setselect(et_statconfig sconfig, int val) : for selection of all events and no filtering set val to ET_STATION_SELECT_ALL. For selection using a user-defined routine loaded through a shared library set it to ET_STATION_SELECT_USER. The ET_STATION_SELECT_MATCH option takes an event's array of control integers and does a comparison with the station's selection integers or words. The first pair is checked for equality, the next a bitwise AND, then back to equality, then a bitwise AND, etc. The results of all logical comparisons are ORed together. An event is selected if result = 1. This may seem strange but is a holdover from the DD system which was a precursor to the ET system and can occasionally be useful. For parallel station there are 2 more possibilities. ET_STATION_SELECT_RROBIN distributes events to a group of parallel stations with a round robin algorithm. ET_STATION_SELECT_EQUALCUE distributes events so that the input queues of each parallel station will be kept the equally full (as much as possible). See below for more details. The default mode is ET_STATION_SELECT_ALL.

8.      et_station_config_setselectwords(et_statconfig sconfig, int *val) : the argument is an array of integers used when the station select mode is set to ET_STATION_SELECT_MATCH (or possibly ET_STATION_SELECT_USER depending on what algorithm a user-defined, event selection routine uses). These integers are compared to the incoming events’ control word array. The default is to set all integers to a value of "-1".

9.      et_station_config_setlib(et_statconfig sconfig, char *val) : for a select mode of ET_STATION_SELECT_USER, val is the name of the shared library containing the function to be used for selecting events.

10.  et_station_config_setfunction(et_statconfig sconfig, char *val) : for a select mode of ET_STATION_SELECT_USER, val is the name of the function to be used for selecting events.

11.  et_station_config_setclass(et_statconfig sconfig, char *val) : when defining a station on a Java-based ET system with a select mode of ET_STATION_SELECT_USER, val is the name of the class containing the method to be used for selecting events.

Just a few notes on some of the details. When selecting the ET_STATION_RESTORE_IN/REDIST modes for event restoration, be aware of a few things. If there is only one process attached to such a station and it dies, the events go to the output list in order to prevent them from being lost to a station with no event readers. If there is more than one process attached and one dies, its events will be put into the input list or the previous station’s output list with the assumption that the recovered events are higher in priority to those already in the station's input list. To be exact, the recovered high priority events are placed "above" (sooner to be read) all other events, and the recovered low priority events are placed below high priority but above all other low priority events. There are no guarantees that the recovered events will be in their original order.

The mode denoted by ET_STATION_SELECT_MATCH has the following behavior. A check is made to see if the first element of the station's selection array is equal to -1. If it is, then the first element of the event's control array is ignored and the event is not marked for selection. Similar comparisons continue for each element of the arrays. Thus, if all elements of a station's selection array are set to -1, the event will NOT be selected. If the first element of the station's selection array is not -1 but is equal to the first element of the event's control array, then the event is selected. If the bitwise AND (&) of the station's and event's second elements is true, then the event is selected. This pattern is repeated with the even elements 0,2,4, 6, ... compared for equality and the odd elements 1, 3, 5, ... compared for bitwise AND. If any of the comparisons are true, then the event is selected. This is the logic employed by the old DD system in its "conditional" mode.

Similar functions to those mentioned above are available to GET the values associated with a station configuration.

Examples

Since one of the more difficult tasks facing the first time user is how to properly configure a station, let's look at two examples first:

/* declarations */
et_stat_config sconfig;
/* set values */
et_station_config_init(&sconfig);
et_station_config_setselect(sconfig, ET_STATION_SELECT_ALL);
et_station_config_setblock(sconfig, ET_STATION_NONBLOCKING);
et_station_config_setuser(sconfig, ET_STATION_USER_SINGLE);
et_station_config_setrestore(sconfig, ET_STATION_RESTORE_GC);
et_station_config_setcue(sconfig, 20);

Here is a station to which only 1 user may attach. It accepts all events no matter what values the selection integers have. It is non-blocking, meaning that once the system fills up its input list with a maximum of 20 events, all other events will bypass the station and be placed somewhere downstream. If the user process should die, the events that it owns will be placed back in GRAND_CENTRAL station, and no one else will get them.

A more complicated example can be seen below:
 
/* declarations */
int selections[] = {17,22,-1,-1};
et_stat_config sconfig;
/* set values */
et_station_config_init(&sconfig);
et_station_config_setselect(sconfig, ET_STATION_SELECT_ALL);
et_station_config_setblock(sconfig, ET_STATION_BLOCKING);
et_station_config_setuser(sconfig, ET_STATION_USER_MULTI);
et_station_config_setrestore(sconfig, ET_STATION_RESTORE_IN);
et_station_config_setprescale(sconfig, 5);
et_station_config_setselect(sconfig, ET_STATION_SELECT_USER);
et_station_config_setselectwords(sconfig, selections);
if (et_station_config_setlib(sconfig, "/stuff/libet_user.so") == ET_ERROR) {
  printf(" cannot set library\n");
}
if (et_station_config_setfunction(sconfig, "et_my_function") == ET_ERROR) {
  printf("cannot set function\n");
}

In the above example, there is a station to which multiple users can attach. Its select mode (ET_STATION_SELECT_USER) says that the user will be supplying a function in a shared library to determine which events are to be selected. Since this station is set to block events, all events which meet its selection criteria are placed in its input list, even if it means slowing the whole ET system down to a crawl. Actually, the prescale factor imposes an additional selection criterion since it is in blocking mode. Thus, only every 5th event which passes through the user's filter gets placed in the station's input list. Its restore mode says that if this user process should ever die, the events that it currently owns will be placed in the station's input list.

Creation & Removal of Stations

Once a configuration is defined, it is passed to the function et_station_create(et_sys_id id, et_stat_id *stat_id, char *stat_name, et_statconfig sconfig). In addition to the arguments, id and sconfig, which have already been covered, the user must supply a unique name and is returned a station identification number stat_id. This station id is used in other station-related routines.

A more detailed version of the above function is et_station_create_at(et_sys_id id, et_stat_id *stat_id, const char *stat_name, et_statconfig sconfig, int position, int parallelposition. Position refers to the position in the list of stations (starting with GRAND_CENTRAL) in which to place the new station. If adding at the end, use the value ET_END for position. Note that the value of position is found by counting a single group of parallel stations as one. If adding the first parallel station of a group of parallel stations, set parallelposition to ET_HEAD since it will be the new head of this group. Once the head parallel station is created, the parallelposition of additional parallel stations must be >= 1 or ET_END.

Possible errors returned by the function et_station_create are ET_ERROR_EXISTS if a station by that name exists already, ET_ERROR_TOOMANY if the user is the second user to try to attach to a station designated for one user only, or ET_ERROR for other unrecoverable errors such as bad positions. If the user is a remote consumer, the error ET_ERROR_REMOTE indicates a bad arg or not being able to allocate memory, and ET_ERROR_READ & ET_ERROR_WRITE indicate problems with the network communication.

Removing stations can be accomplished by calling et_station_remove(et_sys_id id, et_stat_id stat_id).

Attaching to and Detaching from Stations

Until a user's process attaches to a station, the station is placed in an idle mode, meaning, that it is not participating in the flow of events - it is getting by-passed. Once a process attaches to a station, it becomes active and begins to receive events. This logic ensures that events do not get stuck in stations with no one to process them or that the entire flow of events does not come to a grinding halt.

Attach to a station by calling et_station_attach(et_sys_id id, et_stat_id stat_id, et_att_id *att). This routine returns a unique attachment number, att, by which a process identifies itself in certain function calls. For example, when reading and writing events, this parameter is required. In this manner, a single process can attach to different stations and yet be differentiated by the ET system. With this type of interface, for example, a user could conceivably have multiple threads with each attached to the same station on a different attachment. The idea is that this id represents a single attachment to a single station. This attachment id is also a way of specifying the ownership of an event - which is important in setting limits on how and where events can flow.

To detach from a station call et_station_detach(et_sys_id id, et_att_id att). If a user is the last one to detach from a station, all of the events left in the station's input list are passed to the output list. In addition, after a user detaches, a search is made for any events that were read but not written back into the ET system by att. They are recovered and placed according to the station's property set by the function et_station_config_setrestore.

Changing a Station's Behavior on the Fly

Some of the parameters that define a station's behavior as well as its position in the linked list of stations may be modified while an ET system is operating. The only thing that cannot be done is to load new user-defined event selection functions or to change the select mode of the station.

The functions used to SET station parameters are listed below along with an explanation for each:

1.      et_station_setposition(et_sys_id id, et_stat_id stat_id, int position, int pposition) : setting position to a positive integer places the station at that position in the linked list of active and idle stations. The position of 0 is prohibited as the first position is reserved for GRAND_CENTRAL station. Set pposition to the desired place among a single group of parallel stations if it is a parallel station, but it may not be 0 (head spot) if a head parallel station already exists.

2.      et_station_setblock(et_sys_id id, et_stat_id stat_id, int val) : setting val to ET_STATION_BLOCKING makes the station block by looking at all events in the system, while setting it to ET_STATION_NONBLOCKING allows the station to fill up a cue of events and when that is full, events flow to the next station downstream.

3.      et_station_setcue(et_sys_id id, et_stat_id stat_id, int val) : when in nonblocking mode, this sets the maximum number of events that are to be in the station's input list ready for reading (in so far as it is possible).

4.      et_station_setprescale(et_sys_id id, et_stat_id stat_id, int val) : when in blocking mode, every Nth event of interest is sent to the user by setting the val to N.

5.      et_station_setuser(et_sys_id id, et_stat_id stat_id, int val) : setting val to ET_STATION_USER_SINGLE allows only one user process to attach to this station, while setting it to ET_STATION_USER_MULTI allows multiple users to attach. Setting it to a positive integer allows only that number of attachments to the station.

6.      et_station_setrestore(et_sys_id id, et_stat_id stat_id, int val) : when a process dies or detaches from a station, the events it read but did not write are recovered and sent to a station's output list if val is set to ET_STATION_RESTORE_OUT. Similarly, it can be sent to the input list with ET_STATION_RESTORE_IN or back to grandcentral station with ET_STATION_RESTORE_GC.

7.      et_station_setselectwords(et_sys_id id, et_stat_id stat_id, int *val) : the argument is an array of integers used when the station select mode is set to ET_STATION_SELECT_MATCH or possibly ET_STATION_SELECT_USER (depending on what algorithm a user-defined, event selection routine uses). For DD users, it is identical to the old "p2ctl" element of the old "fmode" structure.

Similar functions to those mentioned above are available to GET the values associated with a station's configuration. Note that none of the above functions are allowed to modify GRAND_CENTRAL station.

Handling Events

After opening an ET system, creating a station, and attaching to it, users are ready to start creating, reading and writing events.

Creating

When creating a new event, users are called producers. There are two routines that can be used for doing this. The first is for getting a single, blank event by calling et_event_new(et_sys_id id, et_att_id att, et_event **pe, int wait, struct timespec *time, int size). At this point users are familiar with the first two arguments id, and att. The third is a pointer to a pointer to an event. In the code, declare a pointer to an event (i.e. et_event *pe) and pass its address. Upon a successful return, pe points to a new event. The fourth arg, wait, is a flag that can be set by using some predefined macros. By setting this wait to ET_SLEEP, the call will block until the next free event is available. By setting it to ET_ASYNC, the call returns immediately with a status. And by setting it to ET_TIMED, the call waits for the amount of time given by the time arg if no events are immediately available. Be warned that the time specified with ET_TIMED mode is a minimum. First, read access to a station's input list must be obtained and that could take some additional time. Finally, the last arg is the requested size in bytes. If the size is larger than those the system was created with, the newly created event will be declared a special "temporary" event and will allocate the necessary memory. (This, of course, slows things down).

Similarly the user can call et_events_new(et_sys_id id, et_att_id att, et_event *pe[], int wait, struct timespec *time, int size, int num, int *nread) for obtaining an array of new events. In this case, pe is an array of pointers to events, num is the number of events desired, and nread is the number of events actually read and placed into the array (which may be less than what was asked for).

Finally, the user can call et_events_new_group(et_sys_id id, et_att_id att, et_event *pe[], int wait, struct timespec *time, int size, int num, int group, int *nread). This is similar to et_events_new with the exception that only events of the specified event group will be read. There are situations in which several producers need to grab and fill new events. In order to prevent a single producer from grabbing too many events and slowing down or stopping other producers, events in an ET system may be divided into groups. If each producer uses this function with a different group number, none will be starved for events. To get only 1 event from a group, call et_event_new_group. An alternative to using these two functions for getting new events of a specific group is to call the function et_system_setgroup(et_sys_id id, int group) which will set a default group to retrieve events from. Any subsequent calls to et_event(s)_new will only retrieve events from the default group. Using et_system_setgroup to set the group to 0 resets things so events are retrieved from all groups.

Reading

When reading events, users are called consumers. There are two routines that can be used for reading. The first is for reading single events and has the form et_event_get(et_sys_id id, et_att_id att, et_event **pe, int wait, struct timespec *time). The arguments are the same as those for creating a new event but without the size.

The second type of routine is for reading an array of events by using the call, et_events_get(et_sys_id id, et_att_id att, et_event **pe, int wait, struct timespec *time, int num, int *nread). The arguments are almost the same as for reading single events with the exception that the user passes an array of pointers to events. There are also additional arguments specifying the number of events the user wants to read and the number actually read. Although less events may be returned, the user will never get more than the amount asked for.

Writing

After reading an event, the user has access to a number of its properties for manipulation. Routines to accomplish this are given in the following list:

1.      et_event_setpriority(et_event *pe, int pri) : this routine sets the priority of an event, pri, to be ET_HIGH or ET_LOW (default). A high priority means that such an event gets placed below other high priority but above low priority events when placed in a station's input or output list. Thus, high priority events are always the first to be read. No other guarantees are made.

2.      et_event_getpriority(et_event *pe, int *pri) : this routine returns the priority of an event.

3.      et_event_setlength(et_event *pe, int len) : sets the length or size of the event's data in bytes. This may not be larger than the total amount of memory available in the event.

4.      et_event_getlength(et_event *pe, int *len) : returns the length of the event's data in bytes.

5.      et_event_setcontrol(et_event *pe, int con[], int num) : sets the control information of an event. The con argument is an array of integers which control the flow of the event through the ET system, and the num argument gives the size of the array. The maximum size of this array is determined at compile time by ET_STATION_SELECT_INTS which defaults to 6.

6.      et_event_getcontrol(et_event *pe, int con[]) : gets the event's array of control information.

7.      et_event_getdata(et_event *pe, void **data) : this routine returns a void pointer to the start of an event's data location.

8.      et_event_getdatastatus(et_event *pe, int *status) : this routine gets the status of an event's data. It can be either ET_DATA_OK, ET_DATA_CORRUPT (not currently used), or ET_DATA_POSSIBLY_CORRUPT. Data is ET_DATA_OK unless a previous user got the event from the system and then exited or crashed without putting it back. If the ET system recovers that event and puts it back into the system, its status becomes ET_DATA_POSSIBLY_CORRUPT as a warning to others.

9.      et_event_setendian(et_event *pe, int endian) : though normally the ET system automatically keeps track of the endianness of an event's data, this routine can override and directly set the endian value of the data (but does NOT swap). It may be ET_ENDIAN_BIG, ET_ENDIAN_LITTLE, ET_ENDIAN_LOCAL (same endian as local host), ET_ENDIAN_NOTLOCAL (opposite endian as local host), or ET_ENDIAN_SWITCH. See the chapter Remote ET.

10.  et_event_getendian(et_event *pe, int *endian) : this routine returns the endian of an event's data - either ET_ENDIAN_BIG or ET_ENDIAN_LITTLE. See the chapter Remote ET.

11.  et_event_needtoswap(et_event *pe, int *swap) : this routine tells the caller if an event's data needs to be swapped or not by returning either ET_SWAP or ET_NOSWAP. See the chapter Remote ET.

12.  DEPRECATED: et_event_CODAswap(et_event *pe) : this routine swaps the data of an event in CODA format. This function is deprecated. Use the swap function in the evio library instead.

After setting an event's priority, data length, control array and perhaps its endian value, and writing data, the user is finished with the event and wishes to place it into the ET system. Or perhaps the user has only read the data and is done with the event. In any case, the event must be written back into the system by two possible means. Either write a single event with et_event_put(et_sys_id id, et_att_id att, et_event *pe) or write multiple events with et_events_put(et_sys_id id, et_att_id att, et_event *pe[], int num). In the latter case, the user gives the number, num, of events to put back in the array pe. All events will always be successfully written and will never block as a station's output list has enough room for all events in the whole ET system.

The ET system checks to see if the att that read the event is the same one that is writing it. If it isn't, the call returns an error and nothing is written.

Dumping

After reading existing events or creating new ones, it's possible that these events may no longer be of interest to the user or any other user on the system. In that case, one may dump or recycle these events by calls to two routines. They are identical to the routines et_event(s)_put in their arguments. The first is et_event_dump(et_sys_id id, et_att_id att, et_event *pe) and dumps a single event. Similarly,  et_events_dump(et_sys_id id, et_att_id att, et_event *pe[], int num) dumps multiple events. The dump will place the events directly into GRAND_CENTRAL station’s input list and so no stations downstream will see them.

Closing an ET System

When finished using an ET system, it can be removed from a process' memory by using the et_close(et_sys_id id) routine. This unmaps the ET system memory from the process and makes it inaccessible. It also stops the heartbeat and system-heartbeat-monitor threads. In order to close, all attachments must be detached first. However, there is another function et_forcedclose(et_sys_id id) which will automatically do all the detaching first. Of course, the ET system continues to function for other processes as before.

Killing an ET System

There are occasions on which the user wants administrative control of ET systems. In addition to system creation, the killing and removal of a system can be very useful. In order to kill an ET system process and remove its file, the user must first open the system, then call the et_kill(et_sys_id id) routine. Locally, for the user, this acts as an et_forcedclose.

PreviousNext