improved shutdown procedure
authorVictor Kirhenshtein <victor@netxms.org>
Thu, 28 Sep 2017 13:21:12 +0000 (16:21 +0300)
committerVictor Kirhenshtein <victor@netxms.org>
Thu, 28 Sep 2017 13:21:12 +0000 (16:21 +0300)
src/server/core/console.cpp
src/server/core/datacoll.cpp
src/server/core/main.cpp
src/server/core/objects.cpp
src/server/core/template.cpp
src/server/include/nms_objects.h

index cb031ac..33659c0 100644 (file)
@@ -744,6 +744,7 @@ int ProcessConsoleCommand(const TCHAR *pszCmdLine, CONSOLE_CTX pCtx)
       {
          ShowThreadPoolPendingQueue(pCtx, g_dataCollectorThreadPool, _T("Data collector"));
          ShowQueueStats(pCtx, &g_dciCacheLoaderQueue, _T("DCI cache loader"));
+         ShowQueueStats(pCtx, &g_templateUpdateQueue, _T("Template updates"));
          ShowQueueStats(pCtx, g_dbWriterQueue, _T("Database writer"));
          ShowQueueStats(pCtx, g_dciDataWriterQueue, _T("Database writer (IData)"));
          ShowQueueStats(pCtx, g_dciRawDataWriterQueue, _T("Database writer (raw DCI values)"));
index 83b3f95..97f542e 100644 (file)
@@ -533,6 +533,13 @@ THREAD_RESULT THREAD_CALL CacheLoader(void *arg)
 }
 
 /**
+ * Threads
+ */
+static THREAD s_itemPollerThread = INVALID_THREAD_HANDLE;
+static THREAD s_statCollectorThread = INVALID_THREAD_HANDLE;
+static THREAD s_cacheLoaderThread = INVALID_THREAD_HANDLE;
+
+/**
  * Initialize data collection subsystem
  */
 void InitDataCollector()
@@ -544,9 +551,20 @@ void InitDataCollector()
             ConfigReadInt(_T("DataCollector.ThreadPool.MaxSize"), 250),
             _T("DATACOLL"));
 
-   ThreadCreate(ItemPoller, 0, NULL);
-   ThreadCreate(StatCollector, 0, NULL);
-   ThreadCreate(CacheLoader, 0, NULL);
+   s_itemPollerThread = ThreadCreateEx(ItemPoller, 0, NULL);
+   s_statCollectorThread = ThreadCreateEx(StatCollector, 0, NULL);
+   s_cacheLoaderThread = ThreadCreateEx(CacheLoader, 0, NULL);
+}
+
+/**
+ * Stop data collection
+ */
+void StopDataCollection()
+{
+   ThreadJoin(s_itemPollerThread);
+   ThreadJoin(s_statCollectorThread);
+   ThreadJoin(s_cacheLoaderThread);
+   ThreadPoolDestroy(g_dataCollectorThreadPool);
 }
 
 /**
index dcd0869..4a12fc4 100644 (file)
@@ -75,6 +75,8 @@ void ImportLocalConfiguration();
 void RegisterPredictionEngines();
 void ExecuteStartupScripts();
 void CloseAgentTunnels();
+void StopDataCollection();
+void StopObjectMaintenanceThreads();
 
 void ExecuteScheduledScript(const ScheduledTaskParameters *param);
 void MaintenanceModeEnter(const ScheduledTaskParameters *params);
@@ -1075,6 +1077,9 @@ void NXCORE_EXPORTABLE Shutdown()
                        g_pModuleList[i].pfShutdown();
        }
 
+   StopDataCollection();
+   StopObjectMaintenanceThreads();
+
    DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
        SaveObjects(hdb, INVALID_INDEX, true);
        nxlog_debug(2, _T("All objects saved to database"));
index 644a4ef..f06ac94 100644 (file)
@@ -37,7 +37,7 @@ BusinessServiceRoot NXCORE_EXPORTABLE *g_pBusinessServiceRoot = NULL;
 
 UINT32 NXCORE_EXPORTABLE g_dwMgmtNode = 0;
 
-Queue *g_pTemplateUpdateQueue = NULL;
+Queue g_templateUpdateQueue;
 
 ObjectIndex g_idxObjectById;
 InetAddressIndex g_idxSubnetByAddr;
@@ -64,6 +64,8 @@ static int m_iStatusShift;        // Shift value for "shifted" status propagatio
 static int m_iStatusTranslation[4];
 static int m_iStatusSingleThreshold;
 static int m_iStatusThresholds[4];
+static THREAD s_mapUpdateThread = INVALID_THREAD_HANDLE;
+static THREAD s_applyTemplateThread = INVALID_THREAD_HANDLE;
 
 /**
  * Thread which apply template updates
@@ -72,9 +74,9 @@ static THREAD_RESULT THREAD_CALL ApplyTemplateThread(void *pArg)
 {
    ThreadSetName("ApplyTemplates");
        DbgPrintf(1, _T("Apply template thread started"));
-   while(1)
+   while(!IsShutdownInProgress())
    {
-      TEMPLATE_UPDATE_INFO *pInfo = (TEMPLATE_UPDATE_INFO *)g_pTemplateUpdateQueue->getOrBlock();
+      TEMPLATE_UPDATE_INFO *pInfo = (TEMPLATE_UPDATE_INFO *)g_templateUpdateQueue.getOrBlock();
       if (pInfo == INVALID_POINTER_VALUE)
          break;
 
@@ -127,7 +129,7 @@ static THREAD_RESULT THREAD_CALL ApplyTemplateThread(void *pArg)
       else
       {
                        DbgPrintf(8, _T("ApplyTemplateThread: failed"));
-         g_pTemplateUpdateQueue->put(pInfo);    // Requeue
+         g_templateUpdateQueue.put(pInfo);    // Requeue
          ThreadSleepMs(500);
       }
    }
@@ -210,8 +212,6 @@ void ObjectsInit()
    m_iStatusSingleThreshold = ConfigReadInt(_T("StatusSingleThreshold"), 75);
    ConfigReadByteArray(_T("StatusThresholds"), m_iStatusThresholds, 4, 50);
 
-   g_pTemplateUpdateQueue = new Queue;
-
    // Create "Entire Network" object
    g_pEntireNet = new Network;
    NetObjInsert(g_pEntireNet, false, false);
@@ -1907,15 +1907,25 @@ BOOL LoadObjects()
    }
 
    // Start map update thread
-   ThreadCreate(MapUpdateThread, 0, NULL);
+   s_mapUpdateThread = ThreadCreateEx(MapUpdateThread, 0, NULL);
 
    // Start template update applying thread
-   ThreadCreate(ApplyTemplateThread, 0, NULL);
+   s_applyTemplateThread = ThreadCreateEx(ApplyTemplateThread, 0, NULL);
 
    return TRUE;
 }
 
 /**
+ * Stop object maintenance threads
+ */
+void StopObjectMaintenanceThreads()
+{
+   g_templateUpdateQueue.put(INVALID_POINTER_VALUE);
+   ThreadJoin(s_applyTemplateThread);
+   ThreadJoin(s_mapUpdateThread);
+}
+
+/**
  * Callback for DeleteUserFromAllObjects
  */
 static void DropUserAccess(NetObj *object, void *userId)
index 501ec4d..3526f36 100644 (file)
@@ -997,7 +997,7 @@ void Template::queueUpdate()
          pInfo->pTemplate = this;
          pInfo->targetId = object->getId();
          pInfo->removeDCI = false;
-         g_pTemplateUpdateQueue->put(pInfo);
+         g_templateUpdateQueue.put(pInfo);
       }
    }
    unlockChildList();
@@ -1015,7 +1015,7 @@ void Template::queueRemoveFromTarget(UINT32 targetId, bool removeDCI)
    pInfo->pTemplate = this;
    pInfo->targetId = targetId;
    pInfo->removeDCI = removeDCI;
-   g_pTemplateUpdateQueue->put(pInfo);
+   g_templateUpdateQueue.put(pInfo);
    unlockProperties();
 }
 
index 0f491cf..46e9274 100644 (file)
@@ -2957,7 +2957,7 @@ extern BusinessServiceRoot NXCORE_EXPORTABLE *g_pBusinessServiceRoot;
 
 extern UINT32 NXCORE_EXPORTABLE g_dwMgmtNode;
 extern BOOL g_bModificationsLocked;
-extern Queue *g_pTemplateUpdateQueue;
+extern Queue g_templateUpdateQueue;
 
 extern ObjectIndex NXCORE_EXPORTABLE g_idxObjectById;
 extern InetAddressIndex NXCORE_EXPORTABLE g_idxSubnetByAddr;