fix threading crash in pstats

This commit is contained in:
David Rose 2001-06-12 18:58:04 +00:00
parent f2eddac535
commit 375a2fdeb4
3 changed files with 61 additions and 21 deletions

View File

@ -219,9 +219,7 @@ has_idle() {
////////////////////////////////////////////////////////////////////
bool GtkStatsMonitor::
is_thread_safe() {
// Temporarily set to false to check a possible threading bug. In
// principle, this should work at true.
return false;
return true;
}
////////////////////////////////////////////////////////////////////

View File

@ -122,6 +122,7 @@ lost_connection() {
////////////////////////////////////////////////////////////////////
void PStatReader::
idle() {
dequeue_frame_data();
_monitor->idle();
}
@ -267,24 +268,49 @@ handle_client_udp_data(const Datagram &datagram) {
nassertv(initial_byte == 0);
}
int thread_index = source.get_uint16();
int frame_number = source.get_uint32();
PStatFrameData *frame_data = new PStatFrameData;
frame_data->read_datagram(source, _client_data);
// Check to see if any new collectors have level data.
int num_levels = frame_data->get_num_levels();
for (int i = 0; i < num_levels; i++) {
int collector_index = frame_data->get_level_collector(i);
if (!_client_data->get_collector_has_level(collector_index)) {
// This collector is now reporting level data, and it wasn't
// before.
_client_data->set_collector_has_level(collector_index, true);
_monitor->new_collector(collector_index);
}
if (!_queued_frame_data.full()) {
FrameData data;
data._thread_index = source.get_uint16();
data._frame_number = source.get_uint32();
data._frame_data = new PStatFrameData;
data._frame_data->read_datagram(source, _client_data);
// Queue up the data till we're ready to handle it in a
// single-threaded way.
_queued_frame_data.push_back(data);
}
}
////////////////////////////////////////////////////////////////////
// Function: PStatReader::dequeue_frame_data
// Access: Private
// Description: Called during the idle loop to pull out all the frame
// data that we might have read while the threaded
// reader was running.
////////////////////////////////////////////////////////////////////
void PStatReader::
dequeue_frame_data() {
while (!_queued_frame_data.empty()) {
const FrameData &data = _queued_frame_data.front();
// Check to see if any new collectors have level data.
int num_levels = data._frame_data->get_num_levels();
for (int i = 0; i < num_levels; i++) {
int collector_index = data._frame_data->get_level_collector(i);
if (!_client_data->get_collector_has_level(collector_index)) {
// This collector is now reporting level data, and it wasn't
// before.
_client_data->set_collector_has_level(collector_index, true);
_monitor->new_collector(collector_index);
}
}
_client_data->record_new_frame(data._thread_index,
data._frame_number,
data._frame_data);
_monitor->new_data(data._thread_index, data._frame_number);
_queued_frame_data.pop_front();
}
_client_data->record_new_frame(thread_index, frame_number, frame_data);
_monitor->new_data(thread_index, frame_number);
}

View File

@ -27,10 +27,16 @@
#include <connectionReader.h>
#include <connectionWriter.h>
#include <referenceCount.h>
#include <circBuffer.h>
class PStatServer;
class PStatMonitor;
class PStatClientControlMessage;
class PStatFrameData;
// This is the maximum number of frame records that will be queued up
// from this particular client between processing loops.
static const int queued_frame_records = 500;
////////////////////////////////////////////////////////////////////
// Class : PStatReader
@ -58,6 +64,7 @@ private:
void handle_client_control_message(const PStatClientControlMessage &message);
void handle_client_udp_data(const Datagram &datagram);
void dequeue_frame_data();
private:
PStatServer *_manager;
@ -71,6 +78,15 @@ private:
PT(PStatClientData) _client_data;
string _hostname;
class FrameData {
public:
int _thread_index;
int _frame_number;
PStatFrameData *_frame_data;
};
typedef CircBuffer<FrameData, queued_frame_records> QueuedFrameData;
QueuedFrameData _queued_frame_data;
};
#endif