Panda3D
datagramGeneratorNet.cxx
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 datagramGeneratorNet.cxx
10  * @author drose
11  * @date 2009-02-15
12  */
13 
14 #include "pandabase.h"
15 
16 #include "datagramGeneratorNet.h"
17 #include "mutexHolder.h"
18 #include "lightMutexHolder.h"
19 
20 template class QueuedReturn<Datagram>;
21 
22 /**
23  * Creates a new DatagramGeneratorNet with the indicated number of threads to
24  * handle requests. Normally num_threads should be either 0 or 1 to guarantee
25  * that datagrams are generated in the same order in which they were received.
26  */
28 DatagramGeneratorNet(ConnectionManager *manager, int num_threads) :
29  ConnectionReader(manager, num_threads),
30  _dg_received(_dg_lock),
31  _dg_processed(_dg_lock)
32 {
33 }
34 
35 /**
36  *
37  */
38 DatagramGeneratorNet::
39 ~DatagramGeneratorNet() {
40 }
41 
42 /**
43  * Reads the next datagram from the stream. Blocks until a datagram is
44  * available. Returns true on success, false on stream closed or error.
45  */
47 get_datagram(Datagram &data) {
48  if (is_polling()) {
49  // Single-threaded case: we poll. No need to lock.
50  if (!thing_available()) {
51  if (net_cat.is_spam()) {
52  net_cat.spam()
53  << "DatagramGeneratorNet polling\n";
54  }
55  poll();
56  }
57  while (!thing_available()) {
58  if (is_eof()) {
59  if (net_cat.is_spam()) {
60  net_cat.spam()
61  << "DatagramGeneratorNet returning EOF\n";
62  }
63  return false;
64  }
65  poll();
67  }
68  bool got_dg = get_thing(data);
69  nassertr(got_dg, false);
70 
71  } else {
72  // Threaded case: no polling, we use mutexes and cvars to block instead.
73  MutexHolder holder(_dg_lock);
74  while (!thing_available()) {
75  if (is_eof()) {
76  if (net_cat.is_spam()) {
77  net_cat.spam()
78  << "DatagramGeneratorNet returning EOF\n";
79  }
80  return false;
81  }
82  if (net_cat.is_spam()) {
83  net_cat.spam()
84  << "DatagramGeneratorNet waiting\n";
85  }
86  _dg_received.wait();
87  }
88  bool got_dg = get_thing(data);
89  nassertr(got_dg, false);
90  _dg_processed.notify();
91  }
92 
93  if (net_cat.is_spam()) {
94  net_cat.spam()
95  << "DatagramGeneratorNet returning datagram of length "
96  << data.get_length() << "\n";
97  }
98 
99  return true;
100 }
101 
102 /**
103  * Returns true if the stream has been closed normally. This test may only be
104  * made after a call to get_datagram() has failed.
105  */
107 is_eof() {
108  // We're at eof if we have no more connected sockets.
109  LightMutexHolder holder(_sockets_mutex);
110  return _sockets.empty();
111 }
112 
113 /**
114  * Returns true if the stream has an error condition.
115  */
117 is_error() {
118  // There's an error if any one of our connected sockets reports an error.
119  LightMutexHolder holder(_sockets_mutex);
120  Sockets::const_iterator si;
121  for (si = _sockets.begin(); si != _sockets.end(); ++si) {
122  SocketInfo *sinfo = (*si);
123  if (sinfo->_error) {
124  return true;
125  }
126  }
127 
128  return false;
129 }
130 
131 /**
132  * An internal function called by ConnectionReader() when a new datagram has
133  * become available. This call may be received in a sub-thread.
134  */
135 void DatagramGeneratorNet::
136 receive_datagram(const NetDatagram &datagram) {
137  MutexHolder holder(_dg_lock);
138  while (!enqueue_thing(datagram)) {
139  _dg_processed.wait();
140  }
141  _dg_received.notify();
142 }
void notify()
Informs one of the other threads who are currently blocked on wait() that the relevant condition has ...
void wait()
Waits on the condition.
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...
void poll()
Explicitly polls the available sockets to see if any of them have any noise.
bool is_polling() const
Returns true if the reader is a polling reader, i.e.
virtual bool is_error()
Returns true if the stream has an error condition.
DatagramGeneratorNet(ConnectionManager *manager, int num_threads)
Creates a new DatagramGeneratorNet with the indicated number of threads to handle requests.
virtual bool get_datagram(Datagram &data)
Reads the next datagram from the stream.
virtual bool is_eof()
Returns true if the stream has been closed normally.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
Similar to MutexHolder, but for a light mutex.
A lightweight C++ object whose constructor calls acquire() and whose destructor calls release() on a ...
Definition: mutexHolder.h:25
A specific kind of Datagram, especially for sending across or receiving from a network.
Definition: netDatagram.h:40
static void force_yield()
Suspends the current thread for the rest of the current epoch.
Definition: thread.I:201
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.