示例#1
0
//Track the first instance of our App.
//return TRUE on success, else FALSE
BOOL CInstanceChecker::TrackFirstInstanceRunning()
{
  //If a previous instance is running, just return prematurely
  if (PreviousInstanceRunning())
    return FALSE;

  //If this is the first instance then copy in our info into the shared memory

  //First create the MMF
  int nMMFSize = sizeof(CWindowInstance);
  g_sinstanceData.hInstanceData = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, nMMFSize, GetMMFFilename());
  if (g_sinstanceData.hInstanceData == NULL)
  {
    TRACE(_T("Failed to create the MMF even though this is the first instance, you might want to consider overriding GetMMFFilename()\n"));
    return FALSE;
  }

  //Open the MMF
  CWindowInstance* pInstanceData = static_cast<CWindowInstance*>(MapViewOfFile(g_sinstanceData.hInstanceData, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, nMMFSize));
  ASSERT(pInstanceData != NULL);   //Opening the MMF should work

  //Lock the data prior to updating it
  CSingleLock dataLock(&m_instanceDataMutex, TRUE);
  pInstanceData->hMainWnd = GetWindowToTrack();
  UnmapViewOfFile(pInstanceData);

  //Since this will be the last function that will be called 
  //when this is the first instance we can release the lock
  ReleaseLock();

  return TRUE;
}
void ReasonerStandardImplementation::receivedReasonerNodeHealth(ReasonerMessageReceived & data, NodeHealth & health){
	{	// Disallow other access to aggregated data fields
		unique_lock<mutex> dataLock( dataMutex );

		if ( role == ReasonerStandardImplementationOptions::Role::SYSTEM ){
			(*childNodesHealthMap)[data.reasonerID] = health;
			// OUTPUT( "Received status from node reasoner " << data.reasonerID );
		}
		else if ( role == ReasonerStandardImplementationOptions::Role::PROCESS ){
			// aggregate statistics
			for (int i=0; i < NODE_STATISTIC_COUNT; i++){
				node_statistics[i] += health.statistics[i];
			}
			// OUTPUT( "CPU: " << health.statistics[CONSUMED_CPU_SECONDS] );
			// OUTPUT( "RAPL: " << health.statistics[CONSUMED_ENERGY_JOULE] );

			nodeHealth = make_shared<NodeHealth>(health);

		// OUTPUT( "Received status from node reasoner " << data.reasonerID );
		}
		else if ( data.reasonerID == "INJECT" ) // Workaround for testing!
			nodeHealth = make_shared<NodeHealth>( health );
		else
			ERROR( "Received inappropriate message from " << data.reasonerID << "!" );

		nPushesReceived++;
	}
}
示例#3
0
void CInstanceChecker::QuitPreviousInstance(int nExitCode)
{
  //Try to open the previous instances MMF
  HANDLE hPrevInstance = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, GetMMFFilename());
	if (hPrevInstance)
	{
		// Open up the MMF
		int nMMFSize = sizeof(CWindowInstance);
		CWindowInstance* pInstanceData = static_cast<CWindowInstance*>(MapViewOfFile(hPrevInstance, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, nMMFSize));
		if (pInstanceData != NULL) //Opening the MMF should work
		{
		  // Lock the data prior to reading from it
		  CSingleLock dataLock(&m_instanceDataMutex, TRUE);

		  //activate the old window
		  ASSERT(pInstanceData->hMainWnd); //Something gone wrong with the MMF?
		  HWND hWnd = pInstanceData->hMainWnd;

      //Ask it to exit
      HWND hChildWnd = GetLastActivePopup(hWnd);
  	  PostMessage(hChildWnd, WM_QUIT, nExitCode, 0);
	  }

    //Close the file handle now that we 
    CloseHandle(hPrevInstance);
  }
}
示例#4
0
void EventStatDialog::OnCbnSelchangeComboTimeslice()
{
		CSingleLock dataLock(&m_csEventData);
		dataLock.Lock();
#ifdef _DEBUG
		//if the number of columns is not 4, you need to manually add data below		
		ASSERT(sk_numOfColumns == 4);
#endif
		switch (m_timeSliceComboBox.GetCurSel())
		{
		//for now, just hard code, if someone find a better way to deal with them, feel free to change it.
		case 0:
			m_columnsData[0] = LAST_10S;
			m_columnsData[1] = LAST_30S;
			m_columnsData[2] = LAST_1MIN;
			m_columnsData[3] = LAST_5MINS;
			break;
		case 1:
			m_columnsData[0] = LAST_5MINS;
			m_columnsData[1] = LAST_10MINS;
			m_columnsData[2] = LAST_15MINS;
			m_columnsData[3] = LAST_SINCE_START;
			break;
		default:
			//do nothing
			break;
		}
		UpdateColumnHeader();
		dataLock.Unlock();
	
}
示例#5
0
	void Close( bool bDeleteDevice )
	{
		// Make sure thread is attached to JVM/env
		JNIEnv *env;
		g_JVM->AttachCurrentThread( &env, NULL );
		pthread_setspecific( g_ThreadKey, (void*)env );

		env->CallVoidMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerClose, m_nId );

		hid_mutex_guard dataLock( &m_dataLock );
		m_vecData.clear();

		// Clean and release pending feature report reads
		hid_mutex_guard cvLock( &m_cvLock );
		m_featureReport.clear();
		m_bIsWaitingForFeatureReport = false;
		m_nFeatureReportError = -ECONNRESET;
		pthread_cond_broadcast( &m_cv );

		if ( bDeleteDevice )
		{
			delete m_pDevice;
			m_pDevice = nullptr;
		}
	}
int32
StreamingRingBuffer::Read(void *buffer, size_t length, bool onlyBlockOnNoData)
{
	BAutolock readerLock(fReaderLocker);
	if (!readerLock.IsLocked())
		return B_ERROR;

	BAutolock dataLock(fDataLocker);
	if (!dataLock.IsLocked())
		return B_ERROR;

	int32 readSize = 0;
	while (length > 0) {
		size_t copyLength = min_c(length, fBufferSize - fReadPosition);
		copyLength = min_c(copyLength, fReadable);

		if (copyLength == 0) {
			if (onlyBlockOnNoData && readSize > 0)
				return readSize;

			fReaderWaiting = true;
			dataLock.Unlock();

			status_t result;
			do {
				TRACE("waiting in reader\n");
				result = acquire_sem(fReaderNotifier);
				TRACE("done waiting in reader with status: 0x%08lx\n", result);
			} while (result == B_INTERRUPTED);

			if (result != B_OK)
				return result;

			if (!dataLock.Lock())
				return B_ERROR;

			continue;
		}

		// support discarding input
		if (buffer != NULL) {
			memcpy(buffer, fBuffer + fReadPosition, copyLength);
			buffer = (uint8 *)buffer + copyLength;
		}

		fReadPosition = (fReadPosition + copyLength) % fBufferSize;
		fReadable -= copyLength;
		readSize += copyLength;
		length -= copyLength;

		if (fWriterWaiting) {
			release_sem_etc(fWriterNotifier, 1, B_DO_NOT_RESCHEDULE);
			fWriterWaiting = false;
		}
	}

	return readSize;
}
shared_ptr<SystemHealth> ReasonerStandardImplementation::getSystemHealth(){
	{	// Disallow other access to aggregated data fields
		unique_lock<mutex> dataLock( dataMutex );

		if ( role == ReasonerStandardImplementationOptions::Role::SYSTEM )
			return systemHealth;
	}
	// For other roles, return NULL; this should never happen
	return nullptr;
}
示例#8
0
void EventStatDialog::CleanUpCounters()
{
    CSingleLock dataLock(&m_csEventData);
	dataLock.Lock();
	for(int i = 0; i < NUMBER_OF_EVENT_TYPES;i++)
	{
		m_data[i].clear();
	}
    dataLock.Unlock();
}
shared_ptr<ProcessHealth> ReasonerStandardImplementation::getProcessHealth(){
	{	// Disallow other access to aggregated data fields
		unique_lock<mutex> dataLock( dataMutex );

		if ( role == Role::PROCESS )
			return processHealth;
	}
	// For other roles, return NULL; this should never happen
	return nullptr;
}
示例#10
0
void DataStorage::storageLoop()
{
    isRunning_ = true;
    while (isRunning_)
    {
        //wait until we have data in our queue
        {
            boost::mutex::scoped_lock dataLock(storageMutex_);
            while (dataQueue_.empty())
            {
                queueEmptyCondition_.wait(dataLock);
            }
        }

        //lock the data again for as long as we're storing it
        unsigned int numPackets = 0;
        {
            boost::mutex::scoped_lock dataLock(storageMutex_);
            //create a deferred transaction for the following commands
            //Simple explanation: If we do not wrap everything into a transaction here the performance would be VERY bad
            sqlite::transaction_guard< > transactionGuard(*connection_);

            std::vector<zmq_recorder::Packet>::iterator dataIter = dataQueue_.begin();
            for (; dataIter != dataQueue_.end(); ++dataIter)
            {
                updateData(*dataIter);
            }
            numPackets = dataQueue_.size();
            dataQueue_.clear();

            //commit the transaction (or it will rollback)
            transactionGuard.commit();
        }

        std::cout << getCurrentDateStr() << ": Stored " << numPackets << " packet(s)" << std::endl;

        //sleep some time, this avoids that we do too many transmissions to the database at once
        //it also frees up some time for the CPU
        boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
    }
}
示例#11
0
// Activate the Previous Instance of our Application.
HWND CInstanceChecker::ActivatePreviousInstance()
{
  //Try to open the previous instances MMF
  HANDLE hPrevInstance = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, GetMMFFilename());
  if (hPrevInstance)
  {
    // Open up the MMF
    int nMMFSize = sizeof(CWindowInstance);
    CWindowInstance* pInstanceData = (CWindowInstance*) ::MapViewOfFile(hPrevInstance, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, nMMFSize);
    if (pInstanceData != NULL) //Opening the MMF should work
    {
      // Lock the data prior to reading from it
      CSingleLock dataLock(&m_instanceDataMutex, TRUE);

      //activate the old window
      ASSERT(pInstanceData->hMainWnd); //Something gone wrong with the MMF
      HWND hWindow = pInstanceData->hMainWnd;

      if (hWindow)
      {
        CWnd wndPrev;
        wndPrev.Attach(hWindow);
        CWnd* pWndChild = wndPrev.GetLastActivePopup();

        // Restore the focus to the previous instance and bring it to the foreground
        if (wndPrev.IsIconic())
          wndPrev.ShowWindow(SW_RESTORE);
        pWndChild->SetForegroundWindow();

        //Detach the CWnd we were using
        wndPrev.Detach();
      }

      //Unmap the MMF we were using
      ::UnmapViewOfFile(pInstanceData);

      //Close the file handle now that we 
      ::CloseHandle(hPrevInstance);

      //return the Window handle of the previous instance
      return hWindow;
    }

    //Close the file handle now that we 
    ::CloseHandle(hPrevInstance);

    //When we have activate the previous instance, we can release the lock
    ReleaseLock();
  }

  return NULL;
}
示例#12
0
void EventStatDialog::AddEvent(EventType eventType)
{
    if (m_turnOnEventCollection == false)
    {
        return;
    }
	time_t currentTime;
	time(&currentTime);
	CSingleLock dataLock(&m_csEventData);
	dataLock.Lock();
	m_data[eventType].push_back(currentTime);
	dataLock.Unlock();
}
status_t
StreamingRingBuffer::Write(const void *buffer, size_t length)
{
	BAutolock writerLock(fWriterLocker);
	if (!writerLock.IsLocked())
		return B_ERROR;

	BAutolock dataLock(fDataLocker);
	if (!dataLock.IsLocked())
		return B_ERROR;

	while (length > 0) {
		size_t copyLength = min_c(length, fBufferSize - fWritePosition);
		copyLength = min_c(copyLength, fBufferSize - fReadable);

		if (copyLength == 0) {
			fWriterWaiting = true;
			dataLock.Unlock();

			status_t result;
			do {
				TRACE("waiting in writer\n");
				result = acquire_sem(fWriterNotifier);
				TRACE("done waiting in writer with status: 0x%08lx\n", result);
			} while (result == B_INTERRUPTED);

			if (result != B_OK)
				return result;

			if (!dataLock.Lock())
				return B_ERROR;

			continue;
		}

		memcpy(fBuffer + fWritePosition, buffer, copyLength);
		fWritePosition = (fWritePosition + copyLength) % fBufferSize;
		fReadable += copyLength;

		buffer = (uint8 *)buffer + copyLength;
		length -= copyLength;

		if (fReaderWaiting) {
			release_sem_etc(fReaderNotifier, 1, B_DO_NOT_RESCHEDULE);
			fReaderWaiting = false;
		}
	}

	return B_OK;
}
int ConnectThread::run()
{
	MYSQL* sql = m_mysql->lockHandle();
	if (!mysql_real_connect(sql, stringOrNull(m_host), stringOrNull(m_user), stringOrNull(m_pass), stringOrNull(m_database), m_port, stringOrNull(m_unixSocket), m_clientFlag))
	{
		MutexLocker dataLock(m_dataMutex);
		m_success = false;
		m_error = std::string( mysql_error(sql) );
		postEvent( CONNECTION_FINISHED );

		m_mysql->unlockHandle();
		return 0;
	}
	else
	{
		MutexLocker dataLock(m_dataMutex);
		m_success = true;
		m_error = "";
		postEvent( CONNECTION_FINISHED );

		m_mysql->unlockHandle();
		return 0;
	}
}
void ReasonerStandardImplementation::receivedReasonerSystemHealth(ReasonerMessageReceived & data, SystemHealth & health){
	{	// Disallow other access to aggregated data fields
		unique_lock<mutex> dataLock( dataMutex );

		if ( role == ReasonerStandardImplementationOptions::Role::NODE ){
			// OUTPUT( "Received status from system reasoner " << data.reasonerID );
			systemHealth = make_shared<SystemHealth>(health);
		}
		else if ( data.reasonerID == "INJECT" ) // Workaround for testing!
			systemHealth = make_shared<SystemHealth>( health );
		else
			ERROR( "Received inappropriate message from " << data.reasonerID << "!" );
	}

		nPushesReceived++;
}
void ReasonerStandardImplementation::receivedReasonerProcessHealth(ReasonerMessageReceived & data, ProcessHealth & health){
	{	// Disallow other access to aggregated data fields

		unique_lock<mutex> dataLock( dataMutex );

		// Only Node level reasoners should receive process level reports; others ignore them
		if ( role == ReasonerStandardImplementationOptions::Role::NODE ){
			(*childProcessesHealthMap)[data.reasonerID] = health;
			// OUTPUT( "Received status from process reasoner " << data.reasonerID );
		}
		else if ( data.reasonerID == "INJECT" ) // Workaround for testing!
			processHealth = make_shared<ProcessHealth>( health );
		else
			ERROR( "Received inappropriate message from " << data.reasonerID << "!" );

		nPushesReceived++;
	}
}
ComponentReport ReasonerStandardImplementation::prepareReport() {

	ComponentReport result;

	{	// Disallow other access to aggregated data fields
		unique_lock<mutex> dataLock( dataMutex );

		result.addEntry( "ANOMAL_RUNTIME_MS", ReportEntry( ReportEntry::Type::SIOX_INTERNAL_INFO, VariableDatatype( anomaliesTriggered * update_intervall_ms )));
		result.addEntry( "OBSERVED_RUNTIME_MS", ReportEntry( ReportEntry::Type::SIOX_INTERNAL_INFO, VariableDatatype( cyclesTriggered * update_intervall_ms )));

		result.addEntry( "STATES_SENT_UPSTREAM", ReportEntry( ReportEntry::Type::SIOX_INTERNAL_INFO,  nPushesSent));
		result.addEntry( "STATES_RECEIVED", ReportEntry( ReportEntry::Type::SIOX_INTERNAL_INFO,  nPushesReceived));

		if ( nPushesReceived > 0 ){
			const char * text [] = {
				"UTILIZATION_CPU",
				"UTILIZATION_MEMORY",
				"UTILIZATION_IO",
				"UTILIZATION_NETWORK_SEND",
				"UTILIZATION_NETWORK_RECEIVE",
				"CONSUMED_CPU_SECONDS",
				"CONSUMED_ENERGY_JOULE",
				"CONSUMED_MEMORY_BYTES",
				"CONSUMED_NETWORK_BYTES",
				"CONSUMED_IO_BYTES",
			};

			for (int i=0; i < NODE_STATISTIC_COUNT; i++){
				result.addEntry( text[i], ReportEntry( ReportEntry::Type::APPLICATION_PERFORMANCE,  node_statistics[i] ));
			}
		}

		// for debugging
		ostringstream reportText;
		reportText << this;
		result.addEntry( "TEXT_STATE", ReportEntry( ReportEntry::Type::SIOX_INTERNAL_DEBUG, VariableDatatype( reportText.str() )));
	}

	return result;
}
示例#18
0
void EventStatDialog::UpdateEventsData()
{
	CSingleLock dataLock(&m_csEventData);
	/*if (dataLock.IsLocked())
	{
		return;
	}*/
	dataLock.Lock();	
	time_t currentTime;
	time(&currentTime);
	m_hasBadEventRecently = false;
	for(int i = 0; i < NUMBER_OF_EVENT_TYPES;i++)
	{
		int eventCnt[NUMBER_OF_TIME_SLICE_TYPES];
		for (int n=0; n < NUMBER_OF_TIME_SLICE_TYPES; n++)
		{
			eventCnt[n]=0;
		}
		
		TimeSliceType currentTimeSlice = LAST_15MINS;
		TimeSliceType nextTimeSlice = LAST_10MINS;
		deque<time_t>::iterator eventTime;
		for( eventTime = m_data[i].begin(); eventTime != m_data[i].end();)
		{
            if (m_data[i].empty())
            {
                break;
            }
			double timeDiff = difftime(currentTime,(*eventTime));
			/*
			// hard code version
			if (timeDiff > GetTime(LAST_15MINS))
			{
				//delete this item in the queue
				m_data[i].pop_front();
				eventTime = m_data[i].begin();
				continue;
			}
			else if (timeDiff > GetTime(LAST_10MINS))
			{
				eventCnt[LAST_15MINS]++;
			}
			else if (timeDiff > GetTime(LAST_5MINS))
			{
				eventCnt[LAST_10MINS]++;
			}
			else if (timeDiff > GetTime(LAST_1MIN))
			{
				eventCnt[LAST_5MINS]++;
			}
			else if (timeDiff > GetTime(LAST_30S))
			{
				eventCnt[LAST_1MIN]++;
			}
			else if (timeDiff > GetTime(LAST_10S))
			{
				eventCnt[LAST_30S]++;
			}
			else  
			{
				eventCnt[LAST_10S]++;
			}
			*/
			if (timeDiff > GetTime(currentTimeSlice))
			{
				if (currentTimeSlice == LAST_15MINS)
				{
					//delete this item in the queue
					m_data[i].pop_front();
					eventTime = m_data[i].begin();

					// Increment the RemovedEvents counter to 
					// keep track of # of removed events
					m_numOfRemovedEvents[i]++;
					continue;
				}
				else
				{
					//do nothing, just skip this
				}
			}
			else if (timeDiff > GetTime(nextTimeSlice))
			{
				eventCnt[currentTimeSlice]++;
			}	
			else
			{
				if (nextTimeSlice != LAST_10S)
				{
					currentTimeSlice = nextTimeSlice;
					nextTimeSlice = (TimeSliceType)(nextTimeSlice-1);
					continue;
				}
				else
				{
					eventCnt[LAST_10S]++;
				}
			}
			eventTime++;
		}

		//sum up the number of events
		/*
		//hard code version
		eventCnt[LAST_30S]+=eventCnt[LAST_10S];
		eventCnt[LAST_1MIN]+=eventCnt[LAST_30S];
		eventCnt[LAST_5MINS]+=eventCnt[LAST_1MIN];
		eventCnt[LAST_10MINS]+=eventCnt[LAST_5MINS];
		eventCnt[LAST_15MINS]+=eventCnt[LAST_10MINS];
		*/
		for(unsigned int j=0; j < (unsigned int)NUMBER_OF_TIME_SLICE_TYPES - 1; j++)
		{
			eventCnt[j+1] += eventCnt[j];
		}

		// Adding # of removed events back to "Since Start" time slice category
		eventCnt[NUMBER_OF_TIME_SLICE_TYPES - 1] += m_numOfRemovedEvents[i];

		char buff[32];

		for(int cn = 0; cn < sk_numOfColumns; cn++)
		{
			sprintf(buff,"%d",eventCnt[m_columnsData[cn]]);
			m_eventTable.SetItemText(i, cn + 1, buff);
		}

		// check to see if there is bad event 
		if (IsBadEvent((EventType)i)&&eventCnt[0])
		{
			m_hasBadEventRecently = true;
		}
	}
	dataLock.Unlock();
}
std::string ConnectThread::error()
{
	MutexLocker dataLock(m_dataMutex);
	return m_error;
}
bool ConnectThread::wasSuccessful()
{
	MutexLocker dataLock(m_dataMutex);
	return m_success;
}
void ConnectThread::setClientFlag(unsigned int flag)
{
	MutexLocker dataLock(m_dataMutex);
	m_clientFlag = flag;
}
void ConnectThread::setUnixSocket(const char* socket)
{
	MutexLocker dataLock(m_dataMutex);
	m_unixSocket = safeStrToStr(socket);
}
void ConnectThread::setPort(unsigned int port)
{
	MutexLocker dataLock(m_dataMutex);
	m_port = port;
}
void ConnectThread::setDatabase(const char* db)
{
	MutexLocker dataLock(m_dataMutex);
	m_database = safeStrToStr(db);
}
void ConnectThread::setUserPassword(const char* user, const char* pass)
{
	MutexLocker dataLock(m_dataMutex);
	m_user = safeStrToStr(user);
	m_pass = safeStrToStr(pass);
}
void ConnectThread::setHost(const char* host)
{
	MutexLocker dataLock(m_dataMutex);
	m_host = safeStrToStr(host);
}
示例#27
0
//Activate the Previous Instance of our Application.
HWND CInstanceChecker::ActivatePreviousInstance(LPCTSTR lpCmdLine, ULONG_PTR dwCopyDataItemData, DWORD dwTimeout)
{
  //What will be the return value from this function (assume the worst)
  HWND hWindow = NULL;

  //Try to open the previous instances MMF
  HANDLE hPrevInstance = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, GetMMFFilename());
  if (hPrevInstance)
  {
    //Open up the MMF
    int nMMFSize = sizeof(CWindowInstance);
    CWindowInstance* pInstanceData = static_cast<CWindowInstance*>(MapViewOfFile(hPrevInstance, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, nMMFSize));
    if (pInstanceData) //Opening the MMF should work
    {
      //Lock the data prior to reading from it
      CSingleLock dataLock(&m_instanceDataMutex, TRUE);

      //activate the old window
      ASSERT(pInstanceData->hMainWnd); //Something gone wrong with the MMF
      hWindow = pInstanceData->hMainWnd;
	  if (::IsWindow(hWindow))
      {
        CWnd wndPrev;
        wndPrev.Attach(hWindow);
        CWnd* pWndChild = wndPrev.GetLastActivePopup();

        //Restore the focus to the previous instance and bring it to the foreground
        if (wndPrev.IsIconic())
          wndPrev.ShowWindow(SW_RESTORE);

        if (pWndChild)
          pWndChild->SetForegroundWindow();

        if (lpCmdLine)
        {  
          //Send the current apps command line to the previous instance using WM_COPYDATA
          COPYDATASTRUCT cds;
          cds.dwData = dwCopyDataItemData;
          DWORD dwCmdLength = static_cast<DWORD>(_tcslen(lpCmdLine) + 1);
          cds.cbData = dwCmdLength * sizeof(TCHAR); 
          TCHAR* pszLocalCmdLine = new TCHAR[dwCmdLength]; //We use a local buffer so that we can specify a constant parameter
                                                           //to this function
        #if (_MSC_VER >= 1400)
          _tcscpy_s(pszLocalCmdLine, dwCmdLength, lpCmdLine);
        #else                                                 
          _tcscpy(pszLocalCmdLine, lpCmdLine);
        #endif
          cds.lpData = pszLocalCmdLine;
          CWnd* pMainWindow = AfxGetMainWnd();
          HWND hSender = NULL;
          if (pMainWindow)
            hSender = pMainWindow->GetSafeHwnd();

          //Send the message to the previous instance. Use SendMessageTimeout instead of SendMessage to ensure we 
          //do not hang if the previous instance itself is hung
          DWORD_PTR dwResult = 0;
          if (SendMessageTimeout(hWindow, WM_COPYDATA, reinterpret_cast<WPARAM>(hSender), reinterpret_cast<LPARAM>(&cds),
                                 SMTO_ABORTIFHUNG, dwTimeout, &dwResult) == 0)
          {
            //Previous instance is not responding to messages
            hWindow = NULL;
          }

          //Tidy up the heap memory we have used
          delete [] pszLocalCmdLine;
        }

        //Detach the CWnd we were using
        wndPrev.Detach();
      }

      //Unmap the MMF we were using
      UnmapViewOfFile(pInstanceData);
    }

    //Close the file handle now that we 
    CloseHandle(hPrevInstance);

    //When we have activate the previous instance, we can release the lock
    ReleaseLock();
  }

  return hWindow;
}
void ReasonerStandardImplementation::PeriodicRun(){
	monitoring_namespace_protect_thread();
	bool persistingAnomaly; // Last cycle's anomalyDetected
	bool anomalyDetected = false;

	while( ! terminated ) {
		// OUTPUT( "PeriodicRun started" );

		auto timeout = chrono::system_clock::now() + chrono::milliseconds( update_intervall_ms );

		cyclesTriggered++;

		// Remember last cycle's anomaly state, if persisting anomalies are switched on
		persistingAnomaly = anomalyDetected && kpersistentAnomalies;
		anomalyDetected = false;

		/*
		 * Query all registered ADPIs for news and aggregate them
		 */
		{	// Disallow other access to aggregated data fields
			unique_lock<mutex> dataLock( dataMutex );

			Health * localHealth = nullptr;
			switch (role){
				case ReasonerStandardImplementationOptions::Role::PROCESS :
					localHealth = processHealth.get();
					break;
				case ReasonerStandardImplementationOptions::Role::NODE :
					localHealth = nodeHealth.get();
					break;
				case ReasonerStandardImplementationOptions::Role::SYSTEM :
					localHealth = systemHealth.get();
					break;
				default:
					assert(false && "Invalid process role!");
			}

			{	// Disallow changes in registered plugins while cycling through ADPIs
				unique_lock<mutex> pluginLock( pluginMutex );

				// Query recent observations of all connected plugins and integrate them into the local performance issues.
				// Loop over all registered ADPIs
				for( auto adpi : adpis ) {
					// OUTPUT( "ADPI: " << adpi );
					// Memory management passes to our responsibility here!
					unique_ptr<unordered_map<ComponentID, AnomalyPluginHealthStatistic>>  newObservations = adpi->queryRecentObservations();
					// OUTPUT( "Reports: " << gatheredStatistics->map.size() << " -> " << newObservations->size() );
					// Loop over all reports from current ADPI (by ComponentID)
					for (auto report : *newObservations ) {
						// OUTPUT( "Report for CID: " << report.first );
						// Merge this report into the global set
						// TODO: In Funktion auslagern

						// Merge occurrences into gatheredStatistics and local Health
						for ( int healthState=0; healthState < HEALTH_STATE_COUNT; healthState++ ){
							// OUTPUT( "HealthState = " << healthState );
							// OUTPUT( "Before: " << gatheredStatistics->map[report.first].occurrences[healthState] );
							gatheredStatistics->map[report.first].cid = report.first;
							gatheredStatistics->map[report.first].occurrences[healthState] += report.second.occurrences[healthState];
							// OUTPUT( "After:  " << gatheredStatistics->map[report.first].occurrences[healthState] );
							localHealth->occurrences[healthState] += report.second.occurrences[healthState];
							// OUTPUT( "Updated: " << gatheredStatistics->map[report.first] );

						}

						// Merge positive issues into gatheredStatistics and *localHealth
						unordered_map<string, HealthIssue> * sourceIssueMap = & (report.second.positiveIssues);
						unordered_map<string, HealthIssue> * targetIssueMap = & (gatheredStatistics->map[report.first].positiveIssues);
						list<HealthIssue> * targetIssueList = & (localHealth->positiveIssues);
						for ( auto issue : *sourceIssueMap )
						{
							// OUTPUT( "Received issue: " << issue.second );

							{ // gatheredStatistics
								auto precedent = targetIssueMap->find( issue.first );
								if ( precedent == targetIssueMap->end() )
								{
									(*targetIssueMap)[issue.first] = HealthIssue( issue.first, issue.second.occurrences, issue.second.delta_time_ms );
									// OUTPUT( "Created " << (*targetIssueMap)[issue.first] );
								}
								else
								{
									precedent->second.add(issue.second);
									// OUTPUT( "Added to " << precedent->second );
								}
							}

							{ // *localHealth
								HealthIssue * precedent = nullptr;
								for( auto candidate : *targetIssueList ){
									if ( candidate.name == issue.first )
										precedent = & candidate;
								}
								if( precedent == nullptr )
									targetIssueList->push_back( HealthIssue( issue.first, issue.second.occurrences, issue.second.delta_time_ms ) );
								else
									precedent->add( issue.second );
							}
						}

						// Merge negative issues into gatheredStatistics and *localHealth
						sourceIssueMap = & (report.second.negativeIssues);
						targetIssueMap = & (gatheredStatistics->map[report.first].negativeIssues);
						targetIssueList = & (localHealth->negativeIssues);
						for ( auto issue : *sourceIssueMap )
						{
							// OUTPUT( "Received issue: "<< issue.second );

							{ // gatheredStatistics
								auto precedent = targetIssueMap->find( issue.first );
								if ( precedent == targetIssueMap->end() )
								{
									(*targetIssueMap)[issue.first] = HealthIssue( issue.first, issue.second.occurrences, issue.second.delta_time_ms );
									// OUTPUT( "Created " << (*targetIssueMap)[issue.first] );
								}
								else
								{
									precedent->second.add(issue.second);
									// OUTPUT( "Added to " << precedent->second );
								}
							}

							{ // *localHealth
								HealthIssue * precedent = nullptr;
								for( auto candidate : *targetIssueList ){
									if ( candidate.name == issue.first ){
										precedent = & candidate;
									}
								}
								if( precedent == nullptr )
									targetIssueList->push_back( HealthIssue( issue.first, issue.second.occurrences, issue.second.delta_time_ms ) );
								else
									precedent->add( issue.second );
							}
						}
					}
					// OUTPUT( "Reports: " << gatheredStatistics->map.size() << " -> " << newObservations->size() );
				}
			} // pluginLock

			// Remember last step's statistics for comparison
			oldObservationCounts = observationCounts;
			oldObservationRatios = observationRatios;
			oldObservationTotal = observationTotal;
			// Reset current counts and total
			observationTotal = 0;
			for ( int state = 0; state< HEALTH_STATE_COUNT; state++ )
				observationCounts[state] = 0;
			// Add all gathered statistics by health state
			for ( auto report : gatheredStatistics->map )
				for ( int state = 0; state < HEALTH_STATE_COUNT; state++ )
					observationCounts[state] += report.second.occurrences[state];
			// Total up current counts
			for ( int state = 0; state< HEALTH_STATE_COUNT; state++ )
				observationTotal += observationCounts[state];
			// Compute current ratios
			if( observationTotal > 0 ){
				float scale = 100.0 / observationTotal;
				for ( int state = 0; state< HEALTH_STATE_COUNT; state++ ){
					observationRatios[state] = observationCounts[state] * scale;
					// OUTPUT( observationCounts[state] << "=" << (int) observationRatios[state] << "% " );
				}
			}

			// Check whether anything happened
			if ( observationTotal != oldObservationTotal ){
				// OUTPUT( "Has news: " << oldObservationTotal << "->" << observationTotal );

				// Check whether anything interesting happened
				for (int state = 0; state < HEALTH_STATE_COUNT; ++state)
				{
					// OUTPUT( state << ": " << (int)oldObservationRatios[state] << "->" << (int)observationRatios[state] );
					// Did ratio of any non-OK state move by more than 2 points?
					if( state != HealthState::OK ){
						int diff = observationRatios[state] - oldObservationRatios[state];
						if( abs(diff) >= 2 ){
							anomalyDetected = true;
							// OUTPUT( "Detected an anomaly (moving observation ratio for state " << state << " from " << (int)oldObservationRatios[state] << " to "<< (int)observationRatios[state] << ", or " << observationCounts[state] << " out of " << observationTotal << ")!" );
						}
					}

					// Did number of any ABNORMAL state rise?
					if( state == HealthState::ABNORMAL_BAD

					   || state == HealthState::ABNORMAL_GOOD

					   || state == HealthState::ABNORMAL_OTHER ){
						if( observationCounts[state] > oldObservationCounts[state] ){
							anomalyDetected = true;
							// OUTPUT( "Detected an anomaly (abnormal state " << state << ")!" );
						}
					}
				}
			}

			// TODO combine health of the next level with my local information:
			switch (role){
				case ReasonerStandardImplementationOptions::Role::PROCESS :
					if ( nodeHealth->overallState != GOOD && nodeHealth->overallState != BAD && nodeHealth->overallState != OK ){
						anomalyDetected = true;
					}
					break;
			}



			// Run assessment appropriate to reasoner's role;
			// then, forward current state to remote reasoners
			switch ( role ) {

				case ReasonerStandardImplementationOptions::Role::PROCESS:
					assessProcessHealth();
					if (upstreamReasonerExists){
						// OUTPUT( "Pushing process state upstream!" );
						comm->pushProcessStateUpstream( processHealth);
						nPushesSent++;
					}
					break;

				case ReasonerStandardImplementationOptions::Role::NODE:
					assessNodeHealth();
					if (upstreamReasonerExists){
						// OUTPUT( "Pushing node state upstream!" );
						comm->pushNodeStateUpstream( nodeHealth);
						nPushesSent++;
					}
					break;

				case ReasonerStandardImplementationOptions::Role::SYSTEM:
					assessSystemHealth();
					if (upstreamReasonerExists){
						// OUTPUT( "Pushing system state upstream!" );
						comm->pushSystemStateUpstream( systemHealth);
						nPushesSent++;
					}
					break;

				default:
					break;
			}
		} // dataLock

		// Determine local performance issues based on recent observations and remote issues.


		// now retrieve the nodeStatistics.
		if( nodeStatistics != nullptr ) {

			nodeStatistics->fetchValues();

			for(int i=0; i < NODE_STATISTIC_COUNT ; i++){
				nodeHealth->statistics[i] = (*nodeStatistics)[i].toFloat();
				// OUTPUT( "CurrentNodeStatistics: " << i << " " << nodeHealth->statistics[i] );
			}
		}

		// Save recentIssues
		// TODO

		// Update knownIssues based on recentIssues
		// TODO

		if (anomalyDetected){
			anomaliesTriggered++;
		}
		// Trigger anomaly if any:

		{	// Disallow changes in registered plugins while cycling through triggers
			unique_lock<mutex> pluginLock( pluginMutex );

			if( anomalyDetected || persistingAnomaly ) {
				// OUTPUT( "New anomaly: " << anomalyDetected << "; persisting anomaly: " << persistingAnomaly );
				// OUTPUT( "Calling triggers!" );
				for( auto itr = triggers.begin(); itr != triggers.end() ; itr++ ) {
					( *itr )->triggerResponseForAnomaly(false);
				}
			}
		}

		// OUTPUT( "PeriodicRun() going to sleep..." );
		unique_lock<mutex> lock( recentIssuesMutex );
		// TODO: Understand, clarify and comment this!
		if( terminated ) {
			break;
		}
		running_condition.wait_until( lock, timeout );
	}
	// OUTPUT( "PeriodicRun finished" );
}