Globus XIO introduces a notion of a driver stack to its API.
Globus XIO introduces a notion of a driver stack to its API.
With in globus_xio every IO operation must occur on a globus_xio handle. Associated with each handle is a stack of drivers. A driver is a module piece of code that implements the globus_xio driver interface. The purpose of a driver is manipulate data passed in by the user in someway. Each driver in a stack will serve its own unique purpose.
IO operations pass from driver to driver, starting at the top of the stack and ending at the bottom. When the bottom layer driver finishes with the operation it signals globus_xio that it has completed. Completion notification then follows the driver stack up to the top.
A transport driver is one that is responsible for actually putting bytes onto the wire. For example: A TCP driver or a UDP driver would be an example of transport drivers.
Per driver stack there must be exactly one transport driver and must be at the bottom of the stack. A transform driver is defined by its lack of passing an operation to the next driver in the stack. This type of driver does not rely on globus_xio for further completion of an operation, rather it is self sufficent in this task.
A tranform driver is any intermediate driver in the stack. These drivers are indentified by there reliance on the driver stack to complete the operation. These drivers must pass the operation down the stack because they cannot complete it themselves. An example of a transform driver would be a gsi driver. This driver would wrap and unwrap messages, but would not be able to complete the transport itself, so it would rely on the remaining drivers in the stack.
The globus xio driver api is a set of functions and interfaces to allow a developer to create a backend driver for globus_xio. To create a driver the user must implement all of the interface functions in the driver specification. There are also a set of functions provide to assist the driver author in implemention.
Four basic driver needs the user will have to pay attention to a few new structures and concepts.
This structure represents a request for an operation. If the driver can service the operation it does so and the calls the appropriate finish_operation() function. If the driver cannot completely service the operation it can pass() it along to the next driver in the stack. As soon as the operation structure is either finished or passed it is no longer valid for use in any other function.
A driver_handle represents a open handle to the driver stack for xio. The driver obtains a driver_handle by calling globus_xio_driver_open(). When the open operation completes (it callback is called) the driver then has a driver_handle. The driver_handle allows the user to do some complex things that will be described later.
This structure provides the driver with information about the driver stack It is mainly used for creating driver_handle as a parameter to lobus_xio_driver_open()..
Here is a typcial sequence of events for a globus_xio transform driver:
globus_xio_driver_open_t is called. The user calls globus_xio_driver_open() passing it the operation and the stack and a callback. When the open callback is called the driver is given a new operation as a parameter. The driver will then call globus_xio_driver_finished_open() passing it the now initialized driver_handle and the newly received operation. The call to globus_xio_driver_finished_open() does two things: 1) it tells globus_xio that this driver has finished its open operation, and 2) it gives xio the driver_handle (which contains information on the drivers below it).
The read or write interface funcion is called. It receives a operation as a parameter. The driver then calls the approriate pass operation and waits for the callback. When the callback is received the driver calls finished_operation passing in the operation structure it received in the callback
The close interface function is called and is passed an operation and a driver_handle. The driver will call globus_xio_driver_close() passing it the operation. When the close callback is received the driver calls globus_xio_driver_finished_close() passing it the operation received in the close callback and the driver_handle received in the interface function. At this point the driver_handle is no longer valid..
Advanced Driver Programming
The typical driver implementatin is describe above. However globus_xio allows driver authors to do more advanced things. Some of these things will be explored here.
Once a driver_handle is open a driver can spawn operation structures from it. This gives the driver the ability to request io from the driver stack before it receives a call to its own interface io interface function. So if a driver wishes to read ahead it does the following:
it creats an operation by calling globus_xio_driver_create_operation() and passing it the driver_handle it is intereesting in using.
call globus_xio_driver_read() using this operations. When the read callback is received the driver may call finished_operation() on the op it receives (this ultimitely results in very little, since this operation was started by this driver, but it is good practice and will free up resources that would otherwise leak).
Now when the user finally does receive a read interface call from globus_xio it can imediately finish it using the operation it just received as a parameter and updating the iovec structure to represent the read that already occured.
Once the driver has received a globus_xio_driver_stack_t it can open a driver_handle. The globus_xio_driver_stack_t comes in the call to the interface function globus_xio_server/client_init_t(). The driver uses this structure in a call to globus_xio_driver_open(). When this functionality completes the driver has an initialized driver_handle and can use it to create operations as described above. The driver can now hang onto this driver_handle until it receives an open interface function call. At which time it can call globus_xio_driver_finished_open() passing in the driver_handle and thereby glueing the pre opened driver_handle with the requested globus_xio operation.
Generated automatically by Doxygen for globus xio from the source code.