00001 // Filename: directd.h 00002 // Created by: skyler 2002.04.08 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include <process.h> 00016 #include "pandabase.h" 00017 #include "directsymbols.h" 00018 #include "queuedConnectionManager.h" 00019 #include "queuedConnectionReader.h" 00020 #include "connectionWriter.h" 00021 #include "queuedConnectionListener.h" 00022 #include <windows.h> 00023 00024 00025 #ifdef CPPPARSER //[ 00026 // hack for interrogate 00027 typedef int intptr_t; 00028 typedef int HANDLE; 00029 #endif //] 00030 00031 00032 // Description: DirectD is a client/server app for starting panda/direct. 00033 // 00034 // Usage: 00035 // Start a directd server on each of the machines you 00036 // which to start panda on. 00037 // 00038 // Start a directd client on the controlling machine or 00039 // import ShowBaseGlobal with the xxxxx flag in your 00040 // Configrc. The client will connect each of the servers 00041 // in the xxxxx list in your Configrc. 00042 // 00043 // There are two API groups in this class, they are: 00044 // 00045 // listen_to() 00046 // client_ready() or tell_server() 00047 // wait_for_servers() 00048 // server_ready() 00049 // 00050 // and: 00051 // 00052 // connect_to() 00053 // send_command() 00054 // disconnect_from() 00055 // 00056 // The second group was from a more general implementation 00057 // of DirectD. The first group summarizes the main intents 00058 // of DirectD. 00059 // Both groups are presented in order chronologically by their 00060 // intended usage. 00061 // The first group will probably provide everthing needed for 00062 // DirectD. 00063 class EXPCL_DIRECT DirectD { 00064 PUBLISHED: 00065 DirectD(); 00066 ~DirectD(); 00067 00068 // Description: Call listen_to in the server. 00069 // port is a rendezvous port. 00070 // 00071 // backlog refers to how many connections can queue up 00072 // before you handle them. Consider setting backlog to 00073 // the count you send to wait_for_servers(); or higher. 00074 void listen_to(int port, int backlog=8); 00075 00076 // Description: Call this function from the client when 00077 // import ShowbaseGlobal is nearly finished. 00078 // cmd: a cli command that will be executed on the remote 00079 // machine. 00080 // A new connection will be created and closed. If you 00081 // want to send more than one command, you should use 00082 // connect_to(), send_command(), and disconnect_from(). 00083 int client_ready(const string& server_host, int port, const string& cmd); 00084 00085 // Description: Tell the server to do the command cmd. 00086 // cmd is one of the following: 00087 // "k[<n>]" Kill the most recent application 00088 // started with client_ready() or "!". 00089 // Or kill the nth most recent or 'a' for All. 00090 // E.g. "k", "k0", "k2", "ka". 00091 // "q" Tell the server to quit. 00092 // "!cmd" Exectue the cmd on the server (this 00093 // is a dos shell command; if you want 00094 // a bash command, include bash in the 00095 // command e.g. "!bash pwd"). When you call 00096 // client_ready(), it prefixes "!" for you. 00097 // A new connection will be created and closed. 00098 int tell_server(const string& server_host, int port, const string& cmd); 00099 00100 // Description: Call this function from the client after 00101 // calling <count> client_ready() calls. 00102 // 00103 // Call listen_to(port) prior to calling 00104 // wait_for_servers() (or better yet, prior 00105 // to calling client_ready()). 00106 // 00107 // timeout_ms defaults to two minutes. 00108 bool wait_for_servers(int count, int timeout_ms=2*60*1000); 00109 00110 // Description: Call this function from the server when 00111 // import ShowbaseGlobal is nearly finished. 00112 int server_ready(const string& client_host, int port); 00113 00114 // Description: Call connect_to from client for each server. 00115 // returns the port number of the connection (which 00116 // is different from the rendezvous port used in the 00117 // second argument). The return value can be used 00118 // for the port arguemnt in disconnect_from(). 00119 int connect_to(const string& server_host, int port); 00120 00121 // Description: This is the counterpart to connect_to(). Pass 00122 // the same server_host as for connect_to(), but pass 00123 // the return value from connect_to() for the port, 00124 // not the port passed to connect_to(). 00125 void disconnect_from(const string& server_host, int port); 00126 00127 // Description: Send the same command string to all current 00128 // connections. 00129 void send_command(const string& cmd); 00130 00131 protected: 00132 void start_app(const string& cmd); 00133 void kill_app(int index); 00134 void kill_all(); 00135 virtual void handle_command(const string& cmd); 00136 void handle_datagram(NetDatagram& datagram); 00137 void send_one_message(const string& host_name, 00138 int port, const string& message); 00139 00140 QueuedConnectionManager _cm; 00141 QueuedConnectionReader _reader; 00142 ConnectionWriter _writer; 00143 QueuedConnectionListener _listener; 00144 00145 // Start of old stuff: 00146 // This is used to switch to the original method of 00147 // starting applications. It can be used on old systems 00148 // that don't support job objects. Eventually this stuff 00149 // should be removed. 00150 bool _useOldStuff; 00151 typedef pvector< long /*intptr_t*/ > PidStack; 00152 PidStack _pids; 00153 // End of old stuff 00154 00155 typedef pset< PT(Connection) > ConnectionSet; 00156 ConnectionSet _connections; 00157 HANDLE _jobObject; 00158 bool _shutdown; 00159 00160 void check_for_new_clients(); 00161 void check_for_datagrams(); 00162 void check_for_lost_connection(); 00163 };