diff --git a/panda/src/net/connectionReader.I b/panda/src/net/connectionReader.I index ed663c559e..e9ff4882fd 100644 --- a/panda/src/net/connectionReader.I +++ b/panda/src/net/connectionReader.I @@ -15,7 +15,7 @@ //////////////////////////////////////////////////////////////////// // Function: ConnectionReader::is_polling -// Access: Public +// Access: Published // Description: Returns true if the reader is a polling reader, // i.e. it has no threads. //////////////////////////////////////////////////////////////////// diff --git a/panda/src/net/connectionReader.cxx b/panda/src/net/connectionReader.cxx index 4d4667bc37..9bf311f21f 100644 --- a/panda/src/net/connectionReader.cxx +++ b/panda/src/net/connectionReader.cxx @@ -89,7 +89,7 @@ thread_main() { //////////////////////////////////////////////////////////////////// // Function: ConnectionReader::Constructor -// Access: Public +// Access: Published // Description: Creates a new ConnectionReader with the indicated // number of threads to handle requests. If num_threads // is 0, the sockets will only be read by polling, @@ -137,7 +137,7 @@ ConnectionReader(ConnectionManager *manager, int num_threads) : //////////////////////////////////////////////////////////////////// // Function: ConnectionReader::Destructor -// Access: Public, Virtual +// Access: Published, Virtual // Description: //////////////////////////////////////////////////////////////////// ConnectionReader:: @@ -170,7 +170,7 @@ ConnectionReader:: //////////////////////////////////////////////////////////////////// // Function: ConnectionReader::add_connection -// Access: Public +// Access: Published // Description: Adds a new socket to the list of sockets the // ConnectionReader will monitor. A datagram that comes // in on any of the monitored sockets will be reported. @@ -207,7 +207,7 @@ add_connection(Connection *connection) { //////////////////////////////////////////////////////////////////// // Function: ConnectionReader::remove_connection -// Access: Public +// Access: Published // Description: Removes a socket from the list of sockets being // monitored. Returns true if the socket was correctly // removed, false if it was not on the list in the first @@ -238,7 +238,7 @@ remove_connection(Connection *connection) { //////////////////////////////////////////////////////////////////// // Function: ConnectionReader::is_connection_ok -// Access: Public +// Access: Published // Description: Returns true if the indicated connection has been // added to the ConnectionReader and is being monitored // properly, false if it is not known, or if there was @@ -271,7 +271,7 @@ is_connection_ok(Connection *connection) { //////////////////////////////////////////////////////////////////// // Function: ConnectionReader::poll -// Access: Public +// Access: Published // Description: Explicitly polls the available sockets to see if any // of them have any noise. This function does nothing // unless this is a polling-type ConnectionReader, @@ -315,7 +315,7 @@ poll() { //////////////////////////////////////////////////////////////////// // Function: ConnectionReader::get_manager -// Access: Public +// Access: Published // Description: Returns a pointer to the ConnectionManager object // that serves this ConnectionReader. //////////////////////////////////////////////////////////////////// @@ -326,7 +326,7 @@ get_manager() const { //////////////////////////////////////////////////////////////////// // Function: ConnectionReader::get_num_threads -// Access: Public +// Access: Published // Description: Returns the number of threads the ConnectionReader // has been created with. //////////////////////////////////////////////////////////////////// @@ -337,7 +337,7 @@ get_num_threads() const { //////////////////////////////////////////////////////////////////// // Function: ConnectionReader::set_raw_mode -// Access: Public +// Access: Published // Description: Sets the ConnectionReader into raw mode (or turns off // raw mode). In raw mode, datagram headers are not // expected; instead, all the data available on the pipe @@ -353,7 +353,7 @@ set_raw_mode(bool mode) { //////////////////////////////////////////////////////////////////// // Function: ConnectionReader::get_raw_mode -// Access: Public +// Access: Published // Description: Returns the current setting of the raw mode flag. // See set_raw_mode(). //////////////////////////////////////////////////////////////////// @@ -364,7 +364,7 @@ get_raw_mode() const { //////////////////////////////////////////////////////////////////// // Function: ConnectionReader::set_tcp_header_size -// Access: Public +// Access: Published // Description: Sets the header size of TCP packets. At the present, // legal values for this are 0, 2, or 4; this specifies // the number of bytes to use encode the datagram length @@ -378,7 +378,7 @@ set_tcp_header_size(int tcp_header_size) { //////////////////////////////////////////////////////////////////// // Function: ConnectionReader::get_tcp_header_size -// Access: Public +// Access: Published // Description: Returns the current setting of TCP header size. // See set_tcp_header_size(). //////////////////////////////////////////////////////////////////// @@ -387,6 +387,30 @@ get_tcp_header_size() const { return _tcp_header_size; } +//////////////////////////////////////////////////////////////////// +// Function: ConnectionReader::shutdown +// Access: Published +// Description: Terminates all threads cleanly. Normally this is +// only called by the destructor, but it may be called +// explicitly before destruction. +//////////////////////////////////////////////////////////////////// +void ConnectionReader:: +shutdown() { + if (_shutdown) { + return; + } + + // First, begin the shutdown. This will tell our threads we want + // them to quit. + _shutdown = true; + + // Now wait for all of our threads to terminate. + Threads::iterator ti; + for (ti = _threads.begin(); ti != _threads.end(); ++ti) { + (*ti)->join(); + } +} + //////////////////////////////////////////////////////////////////// // Function: ConnectionReader::flush_read_connection // Access: Protected, Virtual @@ -426,29 +450,6 @@ flush_read_connection(Connection *connection) { } } -//////////////////////////////////////////////////////////////////// -// Function: ConnectionReader::shutdown -// Access: Protected -// Description: Terminates all threads cleanly. Normally this is -// only called by the destructor. -//////////////////////////////////////////////////////////////////// -void ConnectionReader:: -shutdown() { - if (_shutdown) { - return; - } - - // First, begin the shutdown. This will tell our threads we want - // them to quit. - _shutdown = true; - - // Now wait for all of our threads to terminate. - Threads::iterator ti; - for (ti = _threads.begin(); ti != _threads.end(); ++ti) { - (*ti)->join(); - } -} - //////////////////////////////////////////////////////////////////// // Function: ConnectionReader::clear_manager // Access: Protected diff --git a/panda/src/net/connectionReader.h b/panda/src/net/connectionReader.h index 327ccb2a82..74dc812fd1 100644 --- a/panda/src/net/connectionReader.h +++ b/panda/src/net/connectionReader.h @@ -86,6 +86,8 @@ PUBLISHED: void set_tcp_header_size(int tcp_header_size); int get_tcp_header_size() const; + void shutdown(); + protected: virtual void flush_read_connection(Connection *connection); virtual void receive_datagram(const NetDatagram &datagram)=0; @@ -102,7 +104,6 @@ protected: }; typedef pvector Sockets; - void shutdown(); void clear_manager(); void finish_socket(SocketInfo *sinfo); diff --git a/panda/src/net/connectionWriter.cxx b/panda/src/net/connectionWriter.cxx index 727715e646..551aefc367 100644 --- a/panda/src/net/connectionWriter.cxx +++ b/panda/src/net/connectionWriter.cxx @@ -73,6 +73,7 @@ ConnectionWriter(ConnectionManager *manager, int num_threads) : _raw_mode = false; _tcp_header_size = tcp_header_size; _immediate = (num_threads <= 0); + _shutdown = false; int i; for (i = 0; i < num_threads; i++) { @@ -156,6 +157,7 @@ get_current_queue_size() const { //////////////////////////////////////////////////////////////////// bool ConnectionWriter:: send(const Datagram &datagram, const PT(Connection) &connection, bool block) { + nassertr(!_shutdown, false); nassertr(connection != (Connection *)NULL, false); nassertr(connection->get_socket()->is_exact_type(Socket_TCP::get_class_type()), false); @@ -196,6 +198,7 @@ send(const Datagram &datagram, const PT(Connection) &connection, bool block) { bool ConnectionWriter:: send(const Datagram &datagram, const PT(Connection) &connection, const NetAddress &address, bool block) { + nassertr(!_shutdown, false); nassertr(connection != (Connection *)NULL, false); nassertr(connection->get_socket()->is_exact_type(Socket_UDP::get_class_type()), false); @@ -321,6 +324,32 @@ get_tcp_header_size() const { return _tcp_header_size; } +//////////////////////////////////////////////////////////////////// +// Function: ConnectionWriter::shutdown +// Access: Published +// Description: Stops all the threads and cleans them up. This is +// called automatically by the destructor, but it may be +// called explicitly before destruction. +//////////////////////////////////////////////////////////////////// +void ConnectionWriter:: +shutdown() { + if (_shutdown) { + return; + } + _shutdown = true; + + // First, shutdown the queue. This will tell our threads they're + // done. + _queue.shutdown(); + + // Now wait for all threads to terminate. + Threads::iterator ti; + for (ti = _threads.begin(); ti != _threads.end(); ++ti) { + (*ti)->join(); + } + _threads.clear(); +} + //////////////////////////////////////////////////////////////////// // Function: ConnectionWriter::clear_manager // Access: Protected @@ -357,22 +386,3 @@ thread_run(int thread_index) { Thread::consider_yield(); } } - -//////////////////////////////////////////////////////////////////// -// Function: ConnectionWriter::shutdown -// Access: Private -// Description: Stops all the threads and cleans them up. -//////////////////////////////////////////////////////////////////// -void ConnectionWriter:: -shutdown() { - // First, shutdown the queue. This will tell our threads they're - // done. - _queue.shutdown(); - - // Now wait for all threads to terminate. - Threads::iterator ti; - for (ti = _threads.begin(); ti != _threads.end(); ++ti) { - (*ti)->join(); - } - _threads.clear(); -} diff --git a/panda/src/net/connectionWriter.h b/panda/src/net/connectionWriter.h index 30a1ac9322..7ec486d45d 100644 --- a/panda/src/net/connectionWriter.h +++ b/panda/src/net/connectionWriter.h @@ -65,13 +65,14 @@ PUBLISHED: void set_tcp_header_size(int tcp_header_size); int get_tcp_header_size() const; + void shutdown(); + protected: void clear_manager(); private: void thread_run(int thread_index); bool send_datagram(const NetDatagram &datagram); - void shutdown(); protected: ConnectionManager *_manager; @@ -80,6 +81,7 @@ private: bool _raw_mode; int _tcp_header_size; DatagramQueue _queue; + bool _shutdown; class WriterThread : public Thread { public: