Panda3D
connectionReader.h
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file connectionReader.h
10  * @author drose
11  * @date 2000-02-08
12  */
13 
14 #ifndef CONNECTIONREADER_H
15 #define CONNECTIONREADER_H
16 
17 #include "pandabase.h"
18 
19 #include "connection.h"
20 
21 #include "pointerTo.h"
22 #include "pmutex.h"
23 #include "lightMutex.h"
24 #include "pvector.h"
25 #include "pset.h"
26 #include "socket_fdset.h"
27 #include "atomicAdjust.h"
28 
29 class NetDatagram;
30 class ConnectionManager;
31 class Socket_Address;
32 class Socket_IP;
33 
34 /**
35  * This is an abstract base class for a family of classes that listen for
36  * activity on a socket and respond to it, for instance by reading a datagram
37  * and serving it (or queueing it up for later service).
38  *
39  * A ConnectionReader may define an arbitrary number of threads (at least one)
40  * to process datagrams coming in from an arbitrary number of sockets that it
41  * is monitoring. The number of threads is specified at construction time and
42  * cannot be changed, but the set of sockets that is to be monitored may be
43  * constantly modified at will.
44  *
45  * This is an abstract class because it doesn't define how to process each
46  * received datagram. See QueuedConnectionReader. Also note that
47  * ConnectionListener derives from this class, extending it to accept
48  * connections on a rendezvous socket rather than read datagrams.
49  */
50 class EXPCL_PANDA_NET ConnectionReader {
51 PUBLISHED:
52  // The implementation here used to involve NSPR's multi-wait interface, but
53  // that got too complicated to manage. It turns out to be difficult to
54  // protect against memory leaks caused by race conditions in that interface,
55  // as designed.
56 
57  // Instead, we do our own multi-wait type stuff. Only one thread at a time
58  // can extract the next-available socket with activity on it. That thread
59  // will either (a) simply extract the next socket from the arrays returned
60  // by a previous call to PR_Poll(), or (b) execute (and possibly block on) a
61  // new call to PR_Poll().
62 
63  explicit ConnectionReader(ConnectionManager *manager, int num_threads,
64  const std::string &thread_name = std::string());
65  virtual ~ConnectionReader();
66 
67  bool add_connection(Connection *connection);
68  bool remove_connection(Connection *connection);
69  bool is_connection_ok(Connection *connection);
70 
71  void poll();
72 
73  ConnectionManager *get_manager() const;
74  INLINE bool is_polling() const;
75  int get_num_threads() const;
76 
77  void set_raw_mode(bool mode);
78  bool get_raw_mode() const;
79 
80  void set_tcp_header_size(int tcp_header_size);
81  int get_tcp_header_size() const;
82 
83  void shutdown();
84 
85 protected:
86  virtual void flush_read_connection(Connection *connection);
87  virtual void receive_datagram(const NetDatagram &datagram)=0;
88 
89  class SocketInfo {
90  public:
91  SocketInfo(const PT(Connection) &connection);
92  bool is_udp() const;
93  Socket_IP *get_socket() const;
94 
95  PT(Connection) _connection;
96  bool _busy;
97  bool _error;
98  };
100 
101  void clear_manager();
102  void finish_socket(SocketInfo *sinfo);
103 
104  virtual bool process_incoming_data(SocketInfo *sinfo);
105  virtual bool process_incoming_udp_data(SocketInfo *sinfo);
106  virtual bool process_incoming_tcp_data(SocketInfo *sinfo);
107  virtual bool process_raw_incoming_udp_data(SocketInfo *sinfo);
108  virtual bool process_raw_incoming_tcp_data(SocketInfo *sinfo);
109 
110 protected:
111  ConnectionManager *_manager;
112 
113  // These structures track the total set of sockets (connections) we know
114  // about.
115  Sockets _sockets;
116  // This is the list of recently-removed sockets. We can't actually delete
117  // them until they're no longer _busy.
118  Sockets _removed_sockets;
119  // Any operations on _sockets are protected by this mutex.
120  LightMutex _sockets_mutex;
121 
122 private:
123  void thread_run(int thread_index);
124 
125  SocketInfo *get_next_available_socket(bool allow_block,
126  int current_thread_index);
127 
128  void rebuild_select_list();
129  void accumulate_fdset(Socket_fdset &fdset);
130 
131 private:
132  bool _raw_mode;
133  int _tcp_header_size;
134  bool _shutdown;
135 
136  class ReaderThread : public Thread {
137  public:
138  ReaderThread(ConnectionReader *reader, const std::string &thread_name,
139  int thread_index);
140  virtual void thread_main();
141 
142  ConnectionReader *_reader;
143  int _thread_index;
144  };
145 
146  typedef pvector< PT(ReaderThread) > Threads;
147  Threads _threads;
148  bool _polling;
149 
150  // These structures are used to manage selecting for noise on available
151  // sockets.
152  Socket_fdset _fdset;
153  Sockets _selecting_sockets;
154  int _next_index;
155  int _num_results;
156  // Threads go to sleep on this mutex waiting for their chance to read a
157  // socket.
158  Mutex _select_mutex;
159 
160  // This is atomically updated with the index (in _threads) of the thread
161  // that is currently waiting on the PR_Poll() call. It contains -1 if no
162  // thread is so waiting.
163  AtomicAdjust::Integer _currently_polling_thread;
164 
165  friend class ConnectionManager;
166  friend class ReaderThread;
167 };
168 
169 #include "connectionReader.I"
170 
171 #endif
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The primary interface to the low-level networking layer in this package.
This is an abstract base class for a family of classes that listen for activity on a socket and respo...
Represents a single TCP or UDP socket for input or output.
Definition: connection.h:29
This is a standard, non-reentrant mutex, similar to the Mutex class.
Definition: lightMutex.h:41
A standard mutex, or mutual exclusion lock.
Definition: pmutex.h:40
A specific kind of Datagram, especially for sending across or receiving from a network.
Definition: netDatagram.h:40
A simple place to store and manipulate tcp and port address for communication layer.
Base functionality for a INET domain Socket This call should be the starting point for all other unix...
Definition: socket_ip.h:27
A thread; that is, a lightweight process.
Definition: thread.h:46
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.