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 }
void set_max_queue_size(int max_size)
Sets the maximum size the queue is allowed to grow to.
A specific kind of Datagram, especially for sending across or receiving from a network.
Definition: netDatagram.h:40
bool insert(const NetDatagram &data, bool block=false)
Inserts the indicated datagram onto the end of the queue, and returns.
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.
A lightweight C++ object whose constructor calls acquire() and whose destructor calls release() on a ...
Definition: mutexHolder.h:25
void notify_all()
Informs all of the other threads who are currently blocked on wait() that the relevant condition has ...
virtual void clear()
Resets the datagram to empty, in preparation for building up a new datagram.
Definition: netDatagram.cxx:78
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool extract(NetDatagram &result)
Extracts a datagram from the head of the queue, if one is available.
int get_max_queue_size() const
Returns the maximum size the queue is allowed to grow to.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void shutdown()
Marks the queue as shutting down, which will eventually cause all threads blocking on extract() to re...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_current_queue_size() const
Returns the current number of things in the queue.