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  */
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  */
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  */
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 }
virtual bool get_datagram(Datagram &data)
Reads the next datagram from the stream.
A specific kind of Datagram, especially for sending across or receiving from a network.
Definition: netDatagram.h:40
bool is_polling() const
Returns true if the reader is a polling reader, i.e.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The primary interface to the low-level networking layer in this package.
A lightweight C++ object whose constructor calls acquire() and whose destructor calls release() on a ...
Definition: mutexHolder.h:25
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static void force_yield()
Suspends the current thread for the rest of the current epoch.
Definition: thread.I:201
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.
virtual bool is_eof()
Returns true if the stream has been closed normally.
Similar to MutexHolder, but for a light mutex.
DatagramGeneratorNet(ConnectionManager *manager, int num_threads)
Creates a new DatagramGeneratorNet with the indicated number of threads to handle requests.
virtual bool is_error()
Returns true if the stream has an error condition.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
void wait()
Waits on the condition.
void notify()
Informs one of the other threads who are currently blocked on wait() that the relevant condition has ...