Skip to content

Commit a87d38e

Browse files
authored
Adjust windows sensors initialization (#21374)
* Chaneg sensor initialization to handle COM setup in the sensor thread * Fix COM initialization handling in sensor thread
1 parent 17cfae4 commit a87d38e

File tree

1 file changed

+41
-23
lines changed

1 file changed

+41
-23
lines changed

src/collectors/windows.plugin/GetSensors.c

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,30 @@ static void netdata_get_sensors()
617617

618618
static void netdata_sensors_monitor(void *ptr __maybe_unused)
619619
{
620+
// Initialize COM for this thread - sensor thread only needs COM for Sensor API, not WMI
621+
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
622+
bool com_initialized = SUCCEEDED(hr);
623+
624+
// RPC_E_CHANGED_MODE means COM was already initialized in a different mode (e.g., COINIT_APARTMENTTHREADED)
625+
// In this case, COM is available but we didn't increment the reference count
626+
if (FAILED(hr) && hr != RPC_E_CHANGED_MODE) {
627+
nd_log(NDLS_COLLECTORS, NDLP_ERR,
628+
"Sensor thread: cannot initialize COM interface (error 0x%lX)", (unsigned long)hr);
629+
return;
630+
}
631+
632+
// Create sensor manager instance for this thread
633+
hr = CoCreateInstance(
634+
&CLSID_SensorManager, NULL, CLSCTX_INPROC_SERVER, &IID_ISensorManager, (void **)&pSensorManager);
635+
if (FAILED(hr)) {
636+
nd_log(NDLS_COLLECTORS, NDLP_ERR,
637+
"Sensor thread: cannot create ISensorManager (error 0x%lX)", (unsigned long)hr);
638+
// Only uninitialize if we successfully initialized COM ourselves
639+
if (com_initialized)
640+
CoUninitialize();
641+
return;
642+
}
643+
620644
heartbeat_t hb;
621645
heartbeat_init(&hb, USEC_PER_SEC);
622646

@@ -628,6 +652,16 @@ static void netdata_sensors_monitor(void *ptr __maybe_unused)
628652

629653
netdata_get_sensors();
630654
}
655+
656+
// Thread cleanup - release sensor manager and uninitialize COM
657+
if (pSensorManager) {
658+
pSensorManager->lpVtbl->Release(pSensorManager);
659+
pSensorManager = NULL;
660+
}
661+
662+
// Only uninitialize if we successfully initialized COM ourselves
663+
if (com_initialized)
664+
CoUninitialize();
631665
}
632666

633667
void dict_sensor_insert(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
@@ -644,24 +678,9 @@ void dict_sensor_insert(const DICTIONARY_ITEM *item __maybe_unused, void *value,
644678

645679
static int initialize(int update_every)
646680
{
647-
// This is an internal plugin, if we initialize these two times, collector will fail. To avoid this
648-
// we call InitializeWMI to verify COM interface was already initialized.
649-
HRESULT hr = InitializeWMI();
650-
if (hr != S_OK) {
651-
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
652-
if (FAILED(hr)) {
653-
nd_log(NDLS_COLLECTORS, NDLP_ERR, "Collector cannot initialize COM interface.");
654-
return -1;
655-
}
656-
}
657-
658-
hr = CoCreateInstance(
659-
&CLSID_SensorManager, NULL, CLSCTX_INPROC_SERVER, &IID_ISensorManager, (void **)&pSensorManager);
660-
if (FAILED(hr)) {
661-
nd_log(NDLS_COLLECTORS, NDLP_ERR, "Collector cannot initialize sensor API.");
662-
CoUninitialize();
663-
return -1;
664-
}
681+
// Note: COM and Sensor API initialization is now done in the sensor thread
682+
// (netdata_sensors_monitor) because COM must be initialized per-thread.
683+
// The sensor thread owns the pSensorManager instance and handles its cleanup.
665684

666685
sensors = dictionary_create_advanced(
667686
DICT_OPTION_DONT_OVERWRITE_VALUE | DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct sensor_data));
@@ -842,12 +861,11 @@ int do_GetSensors(int update_every, usec_t dt __maybe_unused)
842861

843862
void do_Sensors_cleanup()
844863
{
864+
// Wait for sensor thread to finish
865+
// The thread handles its own COM cleanup (CoUninitialize) and pSensorManager release
845866
if (nd_thread_join(sensors_thread_update))
846867
nd_log_daemon(NDLP_ERR, "Failed to join sensors thread update");
847868

848-
if (pSensorManager) {
849-
pSensorManager->lpVtbl->Release(pSensorManager);
850-
851-
CoUninitialize();
852-
}
869+
// Note: pSensorManager is owned and cleaned up by the sensor thread itself
870+
// No additional cleanup needed here since the thread has already released resources
853871
}

0 commit comments

Comments
 (0)