Progress on mingw driver
This commit is contained in:
@@ -2,26 +2,16 @@
|
||||
//
|
||||
// DrivenEngine
|
||||
//
|
||||
// This module achieves two goals:
|
||||
// This module embodies the idea of an "event-driven game engine." We want the
|
||||
// engine to be event-driven because an event-driven engine is a deterministic
|
||||
// state machine. That, in turn, makes it possible to do replay logging.
|
||||
//
|
||||
// * Makes it possible to do replay logging.
|
||||
// * Makes the engine act like a deterministic state machine.
|
||||
// The DrivenEngine module provides two APIs: the 'engine-side' API, and the
|
||||
// 'driver-side' API.
|
||||
//
|
||||
// We want to implement replay logging. That means we want to be able to run
|
||||
// the engine, keeping a log, then "replay" that execution later.
|
||||
//
|
||||
// Unfortunately, I/O makes this difficult. Suppose that during the execution
|
||||
// of the server, the server reads a lua source file. Later, we want to replay
|
||||
// that execution, but the lua source file has changed on disk. When the engine
|
||||
// reads the lua source file, we need it to "read" the data that *used* to be
|
||||
// there, not the data that's currently there.
|
||||
//
|
||||
// To make it work, all I/O has to operate in one of two modes: either it can be
|
||||
// real I/O, or it can be simulated I/O that retrieves data from the logfile.
|
||||
//
|
||||
// This module, DrivenEngine, provides an API for the engine to do all its I/O.
|
||||
// It provides a variety of methods to open sockets, read and write sockets,
|
||||
// read lua source, get the clock, and so forth.
|
||||
// The engine-side API looks like a typical collection of I/O primitives. It
|
||||
// includes methods to open sockets, read and write sockets, read lua source,
|
||||
// get the clock, and so forth.
|
||||
//
|
||||
// But in reality, these I/O functions don't ever call operating system
|
||||
// functions like "read" or "write" or "connect." They don't call the operating
|
||||
@@ -71,15 +61,11 @@
|
||||
// - If the engine asked that the lua source be refreshed, read the source
|
||||
// from disk and call 'drv_set_lua_source'.
|
||||
//
|
||||
// - List all existing channels using drv_list_channels.
|
||||
// - Get a list of recently-closed channels using drv_get_closed_channels.
|
||||
// Close any socket associated with these channels and free all resources.
|
||||
//
|
||||
// - 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.
|
||||
// - Get a list of recently-opened channels using drv_get_opened_channels.
|
||||
// Open new outgoing connections for these channels.
|
||||
//
|
||||
// - Do an OS 'poll'. The poll should include the sockets for all channels
|
||||
// in the channel list, all listening ports, and stdio.
|
||||
@@ -232,32 +218,23 @@ public:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// Run in logging mode. In this mode, the 'drv' methods will write records
|
||||
// into the logfile, making it possible to replay the exact sequence of drv
|
||||
// methods that were invoked. The replay log will be flushed and closed
|
||||
// automatically in the event of a crash, or if it exceeds the maximum size.
|
||||
// The maximum channel ID plus one.
|
||||
//
|
||||
void drv_logmode_write(const std::string &filename, int64_t maxsize);
|
||||
static const int MAX_CHAN = 256;
|
||||
|
||||
// Run in replay mode. In this mode, the only function the driver may call
|
||||
// is 'drv_step_logfile.' Each time this method is called, a single drv_xxx
|
||||
// method will be called, as requested by the logfile.
|
||||
// Get a list of all recently-closed channels. The driver should
|
||||
// discard all socket information associated with these channels.
|
||||
// Caution: this may contain channels that the driver has never
|
||||
// heard of. In that case, just ignore the close-request.
|
||||
//
|
||||
void drv_logmode_replay(const std::string &filename);
|
||||
|
||||
// Run in non-logging mode. In this mode, no logfile will be read or written
|
||||
// in this mode.
|
||||
//
|
||||
void drv_logmode_none();
|
||||
|
||||
// Get a list of all non-closed existing channels. This may include new
|
||||
// channels that were created using 'new_outgoing_channel'. It may also be
|
||||
// missing channels that were deleted. It is up to the driver to update its
|
||||
// internal data structures to 'match' this list. Channel number zero is
|
||||
// always present, it is the stdio channel.
|
||||
//
|
||||
void drv_list_channels(std::vector<int> &channels);
|
||||
void drv_get_new_closed(std::set<int> &opened);
|
||||
|
||||
// Get a list of all recently-opened channels that were created using
|
||||
// drv_new_outgoing_channel. The driver should initiate outgoing
|
||||
// connections for these channels.
|
||||
//
|
||||
void drv_get_new_outgoing(std::set<int> &closed);
|
||||
|
||||
// Get the target of a channel. A target is a string like
|
||||
// "www.whatever.com:80". It indicates the host and port that the channel
|
||||
// is supposed to be talking to. Non-socket channels and incoming channels
|
||||
@@ -265,6 +242,10 @@ public:
|
||||
//
|
||||
const std::string &drv_get_target(int chid);
|
||||
|
||||
// Return true if the outgoing buffer is empty.
|
||||
//
|
||||
bool drv_outgoing_empty(int chid);
|
||||
|
||||
// Get a pointer to the bytes in the outgoing buffer. The pointer returned
|
||||
// here is naturally only valid until the buffer is changed. This function
|
||||
// is used for all channels, including sockets and stdio.
|
||||
@@ -281,7 +262,7 @@ public:
|
||||
// bytes to be appended to the incoming buffer. This function is used for
|
||||
// all channels, including sockets and stdio.
|
||||
//
|
||||
void drv_recv_incoming(int chid, int nbytes, char *bytes);
|
||||
void drv_recv_incoming(int chid, int nbytes, const char *bytes);
|
||||
|
||||
// Notify the channel that the connection was closed. This includes all
|
||||
// sorts of closes, including friendly termination, all the way to network
|
||||
@@ -325,11 +306,6 @@ public:
|
||||
//
|
||||
bool drv_get_stop_driver();
|
||||
|
||||
// In replay mode, perform a single step of the logfile. Returns true
|
||||
// if the logfile was not empty.
|
||||
//
|
||||
bool drv_step_logfile();
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Creation and Destruction.
|
||||
@@ -360,15 +336,20 @@ public:
|
||||
static DrivenEngine *get();
|
||||
|
||||
private:
|
||||
// Get a channel by channel ID.
|
||||
// Find a currently-unused channel ID. Channel IDs
|
||||
// are small integers that are reused.
|
||||
int find_unused_chid();
|
||||
|
||||
// Get the channel associated with the specified channel ID.
|
||||
Channel *get_chid(int chid);
|
||||
|
||||
private:
|
||||
Channel *channels_[MAX_CHAN];
|
||||
int next_unused_chid_;
|
||||
std::unique_ptr<Channel> stdio_channel_;
|
||||
int next_channel_id_;
|
||||
std::map<int, Channel *> channels_;
|
||||
Channel *recent_channel_;
|
||||
std::vector<std::unique_ptr<Channel>> accepted_channels_;
|
||||
std::set<int> new_closed_;
|
||||
std::set<int> new_outgoing_;
|
||||
util::LuaSourcePtr lua_source_;
|
||||
bool rescan_lua_source_;
|
||||
double clock_;
|
||||
|
||||
Reference in New Issue
Block a user