From c0c2bb98a23b649c55e5d8a55395073fdaa8d6fa Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Fri, 3 Sep 2021 12:11:31 +1000 Subject: [PATCH] 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 --- CommandLine.c | 6 ++---- DynamicColumn.c | 7 +++++++ DynamicColumn.h | 2 ++ DynamicMeter.c | 7 +++++++ DynamicMeter.h | 2 ++ darwin/Platform.h | 4 ++++ dragonflybsd/Platform.h | 4 ++++ freebsd/Platform.h | 4 ++++ linux/Platform.h | 4 ++++ netbsd/Platform.h | 4 ++++ openbsd/Platform.h | 4 ++++ pcp/PCPDynamicColumn.c | 12 ++++++++++++ pcp/PCPDynamicColumn.h | 2 ++ pcp/PCPDynamicMeter.c | 16 ++++++++++++++++ pcp/PCPDynamicMeter.h | 2 ++ pcp/Platform.c | 8 ++++++++ pcp/Platform.h | 4 ++++ solaris/Platform.h | 4 ++++ unsupported/Platform.h | 4 ++++ 19 files changed, 96 insertions(+), 4 deletions(-) diff --git a/CommandLine.c b/CommandLine.c index ecfc731e..f0d22557 100644 --- a/CommandLine.c +++ b/CommandLine.c @@ -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; } diff --git a/DynamicColumn.c b/DynamicColumn.c index e71ff374..c6a0cc03 100644 --- a/DynamicColumn.c +++ b/DynamicColumn.c @@ -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); } diff --git a/DynamicColumn.h b/DynamicColumn.h index a05c81bb..4760e6ea 100644 --- a/DynamicColumn.h +++ b/DynamicColumn.h @@ -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); diff --git a/DynamicMeter.c b/DynamicMeter.c index da342cba..16c27f83 100644 --- a/DynamicMeter.c +++ b/DynamicMeter.c @@ -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; diff --git a/DynamicMeter.h b/DynamicMeter.h index eb35064a..3ef0176a 100644 --- a/DynamicMeter.h +++ b/DynamicMeter.h @@ -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); diff --git a/darwin/Platform.h b/darwin/Platform.h index cd90dd96..e7647dbc 100644 --- a/darwin/Platform.h +++ b/darwin/Platform.h @@ -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; } diff --git a/dragonflybsd/Platform.h b/dragonflybsd/Platform.h index 85b70ab2..48ed1e93 100644 --- a/dragonflybsd/Platform.h +++ b/dragonflybsd/Platform.h @@ -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; } diff --git a/freebsd/Platform.h b/freebsd/Platform.h index 9bc72c7b..e7e274cd 100644 --- a/freebsd/Platform.h +++ b/freebsd/Platform.h @@ -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 diff --git a/linux/Platform.h b/linux/Platform.h index ccc92e19..0d6d4a97 100644 --- a/linux/Platform.h +++ b/linux/Platform.h @@ -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; } diff --git a/netbsd/Platform.h b/netbsd/Platform.h index 4ba4c84b..0420ad13 100644 --- a/netbsd/Platform.h +++ b/netbsd/Platform.h @@ -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; } diff --git a/openbsd/Platform.h b/openbsd/Platform.h index 3e2ec48a..bf43ae5f 100644 --- a/openbsd/Platform.h +++ b/openbsd/Platform.h @@ -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; } diff --git a/pcp/PCPDynamicColumn.c b/pcp/PCPDynamicColumn.c index 3c4e6797..29dc9f91 100644 --- a/pcp/PCPDynamicColumn.c +++ b/pcp/PCPDynamicColumn.c @@ -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); diff --git a/pcp/PCPDynamicColumn.h b/pcp/PCPDynamicColumn.h index 28f3d5ca..d0ffe719 100644 --- a/pcp/PCPDynamicColumn.h +++ b/pcp/PCPDynamicColumn.h @@ -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); diff --git a/pcp/PCPDynamicMeter.c b/pcp/PCPDynamicMeter.c index 430f41c9..ccea8134 100644 --- a/pcp/PCPDynamicMeter.c +++ b/pcp/PCPDynamicMeter.c @@ -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); diff --git a/pcp/PCPDynamicMeter.h b/pcp/PCPDynamicMeter.h index 3da7c35b..0e5ddd2b 100644 --- a/pcp/PCPDynamicMeter.h +++ b/pcp/PCPDynamicMeter.h @@ -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); diff --git a/pcp/Platform.c b/pcp/Platform.c index c2af2e4a..29055b99 100644 --- a/pcp/Platform.c +++ b/pcp/Platform.c @@ -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) diff --git a/pcp/Platform.h b/pcp/Platform.h index dcb8dc98..14e57469 100644 --- a/pcp/Platform.h +++ b/pcp/Platform.h @@ -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); diff --git a/solaris/Platform.h b/solaris/Platform.h index caf296b8..0a379a19 100644 --- a/solaris/Platform.h +++ b/solaris/Platform.h @@ -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; } diff --git a/unsupported/Platform.h b/unsupported/Platform.h index 9ce2c492..cdf1d0f8 100644 --- a/unsupported/Platform.h +++ b/unsupported/Platform.h @@ -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; }