Add completion handling for dynamic meters and columns

Be sure to free dynamic memory allocated for meters and
columns strings, no-op on platforms other than pcp.

Closes #774
This commit is contained in:
Nathan Scott 2021-09-03 12:11:31 +10:00 committed by BenBE
parent 9b30870eec
commit c0c2bb98a2
19 changed files with 96 additions and 4 deletions

View File

@ -393,10 +393,8 @@ int CommandLine_run(const char* name, int argc, char** argv) {
/* Delete these last, since they can get accessed in the crash handler */
Settings_delete(settings);
if (dc)
Hashtable_delete(dc);
if (dm)
Hashtable_delete(dm);
DynamicColumns_delete(dc);
DynamicMeters_delete(dm);
return 0;
}

View File

@ -22,6 +22,13 @@ Hashtable* DynamicColumns_new(void) {
return Platform_dynamicColumns();
}
void DynamicColumns_delete(Hashtable* dynamics) {
if (dynamics) {
Platform_dynamicColumnsDone(dynamics);
Hashtable_delete(dynamics);
}
}
const char* DynamicColumn_init(unsigned int key) {
return Platform_dynamicColumnInit(key);
}

View File

@ -21,6 +21,8 @@ typedef struct DynamicColumn_ {
Hashtable* DynamicColumns_new(void);
void DynamicColumns_delete(Hashtable* dynamics);
const char* DynamicColumn_init(unsigned int key);
const DynamicColumn* DynamicColumn_lookup(Hashtable* dynamics, unsigned int key);

View File

@ -38,6 +38,13 @@ Hashtable* DynamicMeters_new(void) {
return Platform_dynamicMeters();
}
void DynamicMeters_delete(Hashtable* dynamics) {
if (dynamics) {
Platform_dynamicMetersDone(dynamics);
Hashtable_delete(dynamics);
}
}
typedef struct {
unsigned int key;
const char* name;

View File

@ -17,6 +17,8 @@ typedef struct DynamicMeter_ {
Hashtable* DynamicMeters_new(void);
void DynamicMeters_delete(Hashtable* dynamics);
const char* DynamicMeter_lookup(Hashtable* dynamics, unsigned int key);
bool DynamicMeter_search(Hashtable* dynamics, const char* name, unsigned int* key);

View File

@ -99,6 +99,8 @@ void Platform_gettime_monotonic(uint64_t* msec);
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
static inline void Platform_dynamicMetersDone(ATTR_UNUSED Hashtable* table) { }
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
@ -107,6 +109,8 @@ static inline void Platform_dynamicMeterDisplay(ATTR_UNUSED const Meter* meter,
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
static inline void Platform_dynamicColumnsDone(ATTR_UNUSED Hashtable* table) { }
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }

View File

@ -92,6 +92,8 @@ static inline void Platform_gettime_monotonic(uint64_t* msec) {
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
static inline void Platform_dynamicMetersDone(ATTR_UNUSED Hashtable* table) { }
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
@ -100,6 +102,8 @@ static inline void Platform_dynamicMeterDisplay(ATTR_UNUSED const Meter* meter,
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
static inline void Platform_dynamicColumnsDone(ATTR_UNUSED Hashtable* table) { }
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }

View File

@ -92,6 +92,8 @@ static inline void Platform_gettime_monotonic(uint64_t* msec) {
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
static inline void Platform_dynamicMetersDone(ATTR_UNUSED Hashtable* table) { }
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
@ -102,6 +104,8 @@ static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
static inline void Platform_dynamicColumnsDone(ATTR_UNUSED Hashtable* table) { }
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }
#endif

View File

@ -112,6 +112,8 @@ static inline void Platform_gettime_monotonic(uint64_t* msec) {
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
static inline void Platform_dynamicMetersDone(ATTR_UNUSED Hashtable* table) { }
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
@ -120,6 +122,8 @@ static inline void Platform_dynamicMeterDisplay(ATTR_UNUSED const Meter* meter,
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
static inline void Platform_dynamicColumnsDone(ATTR_UNUSED Hashtable* table) { }
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }

View File

@ -96,6 +96,8 @@ static inline void Platform_gettime_monotonic(uint64_t* msec) {
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
static inline void Platform_dynamicMetersDone(ATTR_UNUSED Hashtable* table) { }
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
@ -104,6 +106,8 @@ static inline void Platform_dynamicMeterDisplay(ATTR_UNUSED const Meter* meter,
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
static inline void Platform_dynamicColumnsDone(ATTR_UNUSED Hashtable* table) { }
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }

View File

@ -90,6 +90,8 @@ static inline void Platform_gettime_monotonic(uint64_t* msec) {
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
static inline void Platform_dynamicMetersDone(ATTR_UNUSED Hashtable* table) { }
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
@ -98,6 +100,8 @@ static inline void Platform_dynamicMeterDisplay(ATTR_UNUSED const Meter* meter,
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
static inline void Platform_dynamicColumnsDone(ATTR_UNUSED Hashtable* table) { }
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }

View File

@ -226,6 +226,18 @@ void PCPDynamicColumns_init(PCPDynamicColumns* columns) {
free(path);
}
static void PCPDynamicColumns_free(ATTR_UNUSED ht_key_t key, void* value, ATTR_UNUSED void* data) {
PCPDynamicColumn* column = (PCPDynamicColumn*) value;
free(column->metricName);
free(column->super.heading);
free(column->super.caption);
free(column->super.description);
}
void PCPDynamicColumns_done(Hashtable* table) {
Hashtable_foreach(table, PCPDynamicColumns_free, NULL);
}
void PCPDynamicColumn_writeField(PCPDynamicColumn* this, const Process* proc, RichString* str) {
const PCPProcess* pp = (const PCPProcess*) proc;
unsigned int type = PCPMetric_type(this->id);

View File

@ -26,6 +26,8 @@ typedef struct PCPDynamicColumns_ {
void PCPDynamicColumns_init(PCPDynamicColumns* columns);
void PCPDynamicColumns_done(Hashtable* table);
void PCPDynamicColumn_writeField(PCPDynamicColumn* this, const Process* proc, RichString* str);
int PCPDynamicColumn_compareByKey(const PCPProcess* p1, const PCPProcess* p2, ProcessField key);

View File

@ -283,6 +283,22 @@ void PCPDynamicMeters_init(PCPDynamicMeters* meters) {
free(path);
}
static void PCPDynamicMeter_free(ATTR_UNUSED ht_key_t key, void* value, ATTR_UNUSED void* data) {
PCPDynamicMeter* meter = (PCPDynamicMeter*) value;
for (size_t i = 0; i < meter->totalMetrics; i++) {
free(meter->metrics[i].name);
free(meter->metrics[i].label);
free(meter->metrics[i].suffix);
}
free(meter->metrics);
free(meter->super.caption);
free(meter->super.description);
}
void PCPDynamicMeters_done(Hashtable* table) {
Hashtable_foreach(table, PCPDynamicMeter_free, NULL);
}
void PCPDynamicMeter_enable(PCPDynamicMeter* this) {
for (size_t i = 0; i < this->totalMetrics; i++)
PCPMetric_enable(this->metrics[i].id, true);

View File

@ -33,6 +33,8 @@ typedef struct PCPDynamicMeters_ {
void PCPDynamicMeters_init(PCPDynamicMeters* meters);
void PCPDynamicMeters_done(Hashtable* table);
void PCPDynamicMeter_enable(PCPDynamicMeter* this);
void PCPDynamicMeter_updateValues(PCPDynamicMeter* this, Meter* meter);

View File

@ -363,6 +363,14 @@ void Platform_init(void) {
Platform_getMaxPid();
}
void Platform_dynamicColumnsDone(Hashtable* columns) {
PCPDynamicColumns_done(columns);
}
void Platform_dynamicMetersDone(Hashtable* meters) {
PCPDynamicMeters_done(meters);
}
void Platform_done(void) {
pmDestroyContext(pcp->context);
if (pcp->result)

View File

@ -138,6 +138,8 @@ void Platform_gettime_monotonic(uint64_t* msec);
Hashtable* Platform_dynamicMeters(void);
void Platform_dynamicMetersDone(Hashtable* meters);
void Platform_dynamicMeterInit(Meter* meter);
void Platform_dynamicMeterUpdateValues(Meter* meter);
@ -146,6 +148,8 @@ void Platform_dynamicMeterDisplay(const Meter* meter, RichString* out);
Hashtable* Platform_dynamicColumns(void);
void Platform_dynamicColumnsDone(Hashtable* columns);
const char* Platform_dynamicColumnInit(unsigned int key);
bool Platform_dynamicColumnWriteField(const Process* proc, RichString* str, unsigned int key);

View File

@ -131,6 +131,8 @@ IGNORE_WCASTQUAL_END
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
static inline void Platform_dynamicMetersDone(ATTR_UNUSED Hashtable* table) { }
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
@ -139,6 +141,8 @@ static inline void Platform_dynamicMeterDisplay(ATTR_UNUSED const Meter* meter,
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
static inline void Platform_dynamicColumnsDone(ATTR_UNUSED Hashtable* table) { }
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }

View File

@ -79,6 +79,8 @@ static inline void Platform_gettime_monotonic(uint64_t* msec) {
static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
static inline void Platform_dynamicMetersDone(ATTR_UNUSED Hashtable* table) { }
static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { }
@ -87,6 +89,8 @@ static inline void Platform_dynamicMeterDisplay(ATTR_UNUSED const Meter* meter,
static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
static inline void Platform_dynamicColumnsDone(ATTR_UNUSED Hashtable* table) { }
static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }