Minor tweak for DrivenEngine
This commit is contained in:
@@ -27,11 +27,11 @@
|
||||
// functions like "read" or "write" or "connect." They don't call the operating
|
||||
// system at all - not even indirectly, through a wrapper. Therefore, they
|
||||
// can't really do any I/O. When you use one of these I/O functions to (say)
|
||||
// write some data to a communication channel, the only thing that happens
|
||||
// is that the data is put into a buffer. The actual transmission of the
|
||||
// data happens elsewhere, in what is called the "Driver." Likewise, when you
|
||||
// use one of these I/O functions to read data, it only returns data that
|
||||
// was previously stored by the "Driver."
|
||||
// write some data to a communication channel, the only thing that happens is
|
||||
// that the data is put into a buffer. The actual transmission of the data
|
||||
// happens elsewhere, in what is called the "Driver." Likewise, when you use
|
||||
// one of these I/O functions to read data, it only returns data that was
|
||||
// previously stored by the "Driver."
|
||||
//
|
||||
// The "Driver" is a module that implements the actual I/O. It is highly
|
||||
// OS-dependent code, because it contains code to manipulate sockets, time
|
||||
@@ -47,38 +47,64 @@
|
||||
// DrivenEngine, it's the other way around: the driver calls into class
|
||||
// DrivenEngine to drive it forward. I/O routines drive computation.
|
||||
//
|
||||
// So the upshot of all this is that the DrivenEngine is a deterministic
|
||||
// state machine, free of all OS-specific code.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
// * List all existing channels using drv_list_channels.
|
||||
//
|
||||
// * If there are any new channels in the channel list, use
|
||||
// drv_get_channel_target to fetch the target host, then create a socket and
|
||||
// open the connection. Associate the socket with the channel.
|
||||
//
|
||||
// * Do an OS 'poll'. The poll should include the sockets for all channels in
|
||||
// the channel list, all listening ports, and stdio.
|
||||
//
|
||||
// * If the poll indicates that a listening port has acceptable connections,
|
||||
// accept and call drv_notify_accept. Associate the accepted socket with the
|
||||
// channel.
|
||||
//
|
||||
// * If the poll indicates that a connection can accept outgoing data, use
|
||||
// drv_peek_outgoing to fetch some data to write, and write it. Use
|
||||
// drv_sent_outgoing_bytes to indicate that the data was sent.
|
||||
//
|
||||
// * If the poll indicates that a connection has incoming data, read the data
|
||||
// then push it into the channel using drv_recv_incoming.
|
||||
//
|
||||
// * If the poll indicates that STDIO can be read/written, use
|
||||
// drv_peek_outgoing, drv_sent_outgoing, and drv_recv_incoming in the same
|
||||
// manner as you would for a socket.
|
||||
// So the upshot of all this is that the DrivenEngine is a deterministic state
|
||||
// machine, free of all OS-specific code.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Here are the rules for what the driver must do:
|
||||
//
|
||||
// * Before doing anything else, the driver must select one of the three
|
||||
// logmodes.
|
||||
//
|
||||
// * If 'logmode_replay' is selected, then the driver must proceed to invoke
|
||||
// 'drv_step_logfile' over and over until it returns false. In replay mode,
|
||||
// the driver should not do anything else.
|
||||
//
|
||||
// * If 'logmode_write' or 'logmode_none' is selected, the driver must proceed
|
||||
// to drive the application. Follow the remainder of these steps.
|
||||
//
|
||||
// * Read the lua source from disk, and call 'drv_set_lua_source'.
|
||||
//
|
||||
// * Invoke the DrivenEngine's init callback by calling
|
||||
// 'drv_invoke_engine_init'.
|
||||
//
|
||||
// * Open a hardwired list of ports for listening.
|
||||
//
|
||||
// * Repeat the following steps over and over:
|
||||
//
|
||||
// - List all existing channels using drv_list_channels.
|
||||
//
|
||||
// - If there are any new channels in the channel list, use
|
||||
// drv_get_channel_target to fetch the target host, then create a socket
|
||||
// and open the connection. Associate the socket with the channel.
|
||||
//
|
||||
// - If the channel list is missing a previously-known channel, then that
|
||||
// channel was deleted by the engine. Clean up the channel's data and
|
||||
// close the socket, if any.
|
||||
//
|
||||
// - Do an OS 'poll'. The poll should include the sockets for all channels
|
||||
// in the channel list, all listening ports, and stdio.
|
||||
//
|
||||
// - If the poll indicates that a listening port has acceptable
|
||||
// connections, accept and call drv_notify_accept. Associate the
|
||||
// accepted socket with the channel.
|
||||
//
|
||||
// - If the poll indicates that a connection can accept outgoing data, use
|
||||
// drv_peek_outgoing to fetch some data to write, and write it. Use
|
||||
// drv_sent_outgoing_bytes to indicate that the data was sent.
|
||||
//
|
||||
// - If the poll indicates that a connection has incoming data, read the
|
||||
// data then push it into the channel using drv_recv_incoming.
|
||||
//
|
||||
// - If the poll indicates that STDIO can be read/written, use
|
||||
// drv_peek_outgoing, drv_sent_outgoing, and drv_recv_incoming in the
|
||||
// same manner as you would for a socket.
|
||||
//
|
||||
// - Use 'drv_invoke_engine_update' to invoke the engine's update
|
||||
// callback.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifndef DRIVENENGINE_HPP
|
||||
#define DRIVENENGINE_HPP
|
||||
|
||||
Reference in New Issue
Block a user