Panda3D
Loading...
Searching...
No Matches
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 */
21DatagramQueue::
22DatagramQueue() :
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 */
33DatagramQueue::
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 */
47shutdown() {
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 */
66insert(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 */
99extract(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 */
133set_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 */
143get_max_queue_size() const {
144 return _max_queue_size;
145}
146
147/**
148 * Returns the current number of things in the queue.
149 */
152 MutexHolder holder(_cvlock);
153 int size = _queue.size();
154 return size;
155}
void notify()
Informs one of the other threads who are currently blocked on wait() that the relevant condition has ...
void notify_all()
Informs all of the other threads who are currently blocked on wait() that the relevant condition has ...
void wait()
Waits on the condition.
int get_max_queue_size() const
Returns the maximum size the queue is allowed to grow to.
void shutdown()
Marks the queue as shutting down, which will eventually cause all threads blocking on extract() to re...
void set_max_queue_size(int max_size)
Sets the maximum size the queue is allowed to grow to.
bool extract(NetDatagram &result)
Extracts a datagram from the head of the queue, if one is available.
bool insert(const NetDatagram &data, bool block=false)
Inserts the indicated datagram onto the end of the queue, and returns.
int get_current_queue_size() const
Returns the current number of things in the queue.
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
virtual void clear()
Resets the datagram to empty, in preparation for building up a new datagram.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.