Panda3D

datagramQueue.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 datagramQueue.cxx
10 * @author drose
11 * @date 2000-02-08
12 */
13
14 #include "datagramQueue.h"
15 #include "config_net.h"
16 #include "mutexHolder.h"
17
18 /**
19 *
20 */
21 DatagramQueue::
22 DatagramQueue() :
23 _cvlock("DatagramQueue::_cvlock"),
24 _cv(_cvlock)
25 {
26 _shutdown = false;
27 _max_queue_size = get_net_max_write_queue();
28 }
29
30 /**
31 *
32 */
33 DatagramQueue::
34 ~DatagramQueue() {
35 // It's an error to delete a DatagramQueue without first shutting it down
36 // (and waiting for any associated threads to terminate).
37 nassertv(_shutdown);
38 }
39
40 /**
41 * Marks the queue as shutting down, which will eventually cause all threads
42 * blocking on extract() to return false. The normal way to delete a
43 * DatagramQueue will be to call first shutdown() and then wait for all known
44 * threads to terminate. Then it is safe to delete the queue.
45 */
46 void DatagramQueue::
47 shutdown() {
48 // Notify all of our threads that we're shutting down. This will cause any
49 // thread blocking on extract() to return false.
50 MutexHolder holder(_cvlock);
51
52 _shutdown = true;
53 _cv.notify_all();
54 }
55
56
57 /**
58 * Inserts the indicated datagram onto the end of the queue, and returns. If
59 * the queue is empty and any threads are waiting on the queue, this will wake
60 * one of them up. Returns true if successful, false if the queue was full.
61 *
62 * If block is true, this will not return until successful, waiting until the
63 * queue has space available if necessary.
64 */
65 bool DatagramQueue::
66 insert(const NetDatagram &data, bool block) {
67 MutexHolder holder(_cvlock);
68
69 bool enqueue_ok = ((int)_queue.size() < _max_queue_size);
70 if (block) {
71 while (!enqueue_ok && !_shutdown) {
72 _cv.wait();
73 enqueue_ok = ((int)_queue.size() < _max_queue_size);
74 }
75 }
76
77 if (enqueue_ok) {
78 _queue.push_back(data);
79 }
80 _cv.notify(); // Only need to wake up one thread.
81
82 return enqueue_ok;
83 }
84
85
86 /**
87 * Extracts a datagram from the head of the queue, if one is available. If a
88 * datagram is available, this will immediately return; otherwise, it will
89 * block until a datagram becomes available. Multiple threads may
90 * simultaneously block on extract(); when a datagram is subsequently inserted
91 * into the queue, one of the threads will return from extract() with the
92 * datagram.
93 *
94 * The return value is true if the datagram is successfully extracted, or
95 * false if the queue was destroyed while waiting. (In the case of a false
96 * return, the thread should not attempt to operate on the queue again.)
97 */
98 bool DatagramQueue::
99 extract(NetDatagram &result) {
100 // First, clear the datagram result in case it's got an outstanding
101 // connection pointer--we're about to go to sleep for a while.
102 result.clear();
103
104 MutexHolder holder(_cvlock);
105
106 while (_queue.empty() && !_shutdown) {
107 _cv.wait();
108 }
109
110 if (_shutdown) {
111 return false;
112 }
113
114 nassertr(!_queue.empty(), false);
115 result = _queue.front();
116 _queue.pop_front();
117
118 // Wake up any threads waiting to stuff things into the queue.
119 _cv.notify_all();
120
121 return true;
122 }
123
124 /**
125 * Sets the maximum size the queue is allowed to grow to. This is primarily
126 * for a sanity check; this is a limit beyond which we can assume something
127 * bad has happened.
128 *
129 * It's also a crude check against unfortunate seg faults due to the queue
130 * filling up and quietly consuming all available memory.
131 */
132 void DatagramQueue::
133 set_max_queue_size(int max_size) {
134 MutexHolder holder(_cvlock);
135 _max_queue_size = max_size;
136 }
137
138 /**
139 * Returns the maximum size the queue is allowed to grow to. See
140 * set_max_queue_size().
141 */
142 int DatagramQueue::
143 get_max_queue_size() const {
144 return _max_queue_size;
145 }
146
147 /**
148 * Returns the current number of things in the queue.
149 */
150 int DatagramQueue::
151 get_current_queue_size() const {
152 MutexHolder holder(_cvlock);
153 int size = _queue.size();
154 return size;
155 }
ConditionVarFullDirect::notify
void notify()
Informs one of the other threads who are currently blocked on wait() that the relevant condition has ...
Definition: conditionVarFullDirect.I:85
ConditionVarFullDirect::notify_all
void notify_all()
Informs all of the other threads who are currently blocked on wait() that the relevant condition has ...
Definition: conditionVarFullDirect.I:100
ConditionVarFullDirect::wait
void wait()
Waits on the condition.
Definition: conditionVarFullDirect.I:53
DatagramQueue::get_max_queue_size
int get_max_queue_size() const
Returns the maximum size the queue is allowed to grow to.
Definition: datagramQueue.cxx:143
DatagramQueue::shutdown
void shutdown()
Marks the queue as shutting down, which will eventually cause all threads blocking on extract() to re...
Definition: datagramQueue.cxx:47
DatagramQueue::set_max_queue_size
void set_max_queue_size(int max_size)
Sets the maximum size the queue is allowed to grow to.
Definition: datagramQueue.cxx:133
DatagramQueue::extract
bool extract(NetDatagram &result)
Extracts a datagram from the head of the queue, if one is available.
Definition: datagramQueue.cxx:99
DatagramQueue::insert
bool insert(const NetDatagram &data, bool block=false)
Inserts the indicated datagram onto the end of the queue, and returns.
Definition: datagramQueue.cxx:66
DatagramQueue::get_current_queue_size
int get_current_queue_size() const
Returns the current number of things in the queue.
Definition: datagramQueue.cxx:151
MutexHolder
A lightweight C++ object whose constructor calls acquire() and whose destructor calls release() on a ...
Definition: mutexHolder.h:25
NetDatagram
A specific kind of Datagram, especially for sending across or receiving from a network.
Definition: netDatagram.h:40
NetDatagram::clear
virtual void clear()
Resets the datagram to empty, in preparation for building up a new datagram.
Definition: netDatagram.cxx:78
config_net.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
datagramQueue.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
mutexHolder.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.