Panda3D
Loading...
Searching...
No Matches
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
17#include "mutexHolder.h"
18#include "lightMutexHolder.h"
19
20template 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 */
28DatagramGeneratorNet(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 */
38DatagramGeneratorNet::
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 */
107is_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 */
117is_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 */
135void DatagramGeneratorNet::
136receive_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
This is the implementation of a family of things that queue up their return values for later retrieva...
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.