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::
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::
144  return _max_queue_size;
145 }
146 
147 /**
148  * Returns the current number of things in the queue.
149  */
150 int DatagramQueue::
152  MutexHolder holder(_cvlock);
153  int size = _queue.size();
154  return size;
155 }
MutexHolder
A lightweight C++ object whose constructor calls acquire() and whose destructor calls release() on a ...
Definition: mutexHolder.h:25
DatagramQueue::get_current_queue_size
int get_current_queue_size() const
Returns the current number of things in the queue.
Definition: datagramQueue.cxx:151
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
NetDatagram::clear
virtual void clear()
Resets the datagram to empty, in preparation for building up a new datagram.
Definition: netDatagram.cxx:78
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
config_net.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
datagramQueue.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
ConditionVarFullDirect::wait
void wait()
Waits on the condition.
Definition: conditionVarFullDirect.I:53
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
mutexHolder.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
NetDatagram
A specific kind of Datagram, especially for sending across or receiving from a network.
Definition: netDatagram.h:40
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
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::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