Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: 7ca18e7eec74376fd9c3f507b6f78c26d7ea392e (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12











                                                                                 
                    



                                     

                                                      
                                           

















                                           
 
                     

 



                                               

 





                                                                    
                                                    
                                

 


                                                                      

                                                                                                                                          
                                

 








                                                                                  

 
                                        

                                
                                     

                                                                                                                                         

                         

                                

 



                                       
                                                                                                   

                        
 
                          


                                                             

                                                               











                                                                                        
                                                 


                                            
                                         
                                
                                                       
 



                                                                                          
         
                                

 









                                                               
         
 
 





                                           
         





                                                                                  



                                                                                                                                

                                        


                           
/*******************************************************************************
 * Copyright (c) 2012 Draeger Medical GmbH (http://www.draeger.com).
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * CONTRIBUTORS:
 * 		Peter Karlitschek (initial contribution)
 *
 *******************************************************************************/

#include <algorithm>
#include "MessageServiceController.h"

namespace etRuntime {

MessageServiceController::MessageServiceController() :
		m_messageServices(),
		m_messageServicesOrdered(),
		m_freeIDs(),
		m_running(false),
		m_nextFreeID(0),
		m_terminateServices(){
	etMutex_construct(&m_mutex);
	etSema_construct(&m_terminateSema);
}

int MessageServiceController::getNewID() {
	etMutex_enter(&m_mutex);
	int newID;
	if (m_freeIDs.empty())
		newID = m_nextFreeID++;
	else {
		newID = m_freeIDs.back();
		m_freeIDs.pop();
	}
	etMutex_leave(&m_mutex);

	return newID;
}

void MessageServiceController::freeID(int id) {
	etMutex_enter(&m_mutex);
	m_freeIDs.push(id);
	etMutex_leave(&m_mutex);
}

void MessageServiceController::addMsgSvc(IMessageService& msgSvc) {
	etMutex_enter(&m_mutex);
	if (m_nextFreeID <= msgSvc.getAddress().m_threadID)
		m_nextFreeID = msgSvc.getAddress().m_threadID + 1;

	m_messageServices[msgSvc.getAddress().m_threadID] = &msgSvc;
	m_messageServicesOrdered.push_back(&msgSvc);
	etMutex_leave(&m_mutex);
}

void MessageServiceController::removeMsgSvc(IMessageService& msgSvc) {
	etMutex_enter(&m_mutex);
	m_messageServices.erase(msgSvc.getAddress().m_threadID);
	std::vector<IMessageService*>::iterator it = std::find(m_messageServicesOrdered.begin(), m_messageServicesOrdered.end(), &msgSvc);
	m_messageServicesOrdered.erase(it);
	etMutex_leave(&m_mutex);
}

IMessageService* MessageServiceController::getMsgSvc(int id) {
	IMessageService* msgSvc = 0;
	etMutex_enter(&m_mutex);
	std::map<int, IMessageService*>::iterator it = m_messageServices.find(id);
	if(it != m_messageServices.end())
		msgSvc = it->second;
	etMutex_leave(&m_mutex);

	return msgSvc;
}

void MessageServiceController::start() {
	etMutex_enter(&m_mutex);

	// start all message services
	for (std::vector<IMessageService*>::iterator it = m_messageServicesOrdered.begin(); it != m_messageServicesOrdered.end(); ++it) {
		(*it)->start();
	}
	m_running = true;

	etMutex_leave(&m_mutex);
}

void MessageServiceController::stop() {
	if (!m_running)
		return;

	//dumpThreads("org.eclipse.etrice.runtime.java.messaging.MessageServiceController.stop()");
	terminate();
	waitTerminate();

	m_running = false;
}

void MessageServiceController::dumpThreads(std::string msg) {
//	std::cout << "<<< begin dump threads <<<" << std::endl;
//	std::cout << "=== "  << msg << std::endl;
	//TODO dump stack traces
//		Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
//		for (Thread thread : traces.keySet()) {
//			std::cout << "thread " << thread.getName() << std::endl;
//			StackTraceElement[] elements = traces.get(thread);
//			int n = 2;
//			if (elements.length < n)
//				n = elements.length;
//			for (int i = 0; i < n; i++) {
//				std::cout << " " << elements[i].toString() << std::endl;
//			}
//		}
//	std::cout <<(">>> end dump threads >>>");
}

void MessageServiceController::terminate() {
	// terminate all message services
	etMutex_enter(&m_mutex);
	m_terminateServices = m_messageServicesOrdered;

	// stop in reverse order
	std::vector<IMessageService*>::reverse_iterator it = m_terminateServices.rbegin();
	for (; it != m_terminateServices.rend(); ++it) {
		(*it)->terminate();
	}
	etMutex_leave(&m_mutex);
}

void MessageServiceController::waitTerminate() {
	etBool wait = true;

	while(wait){
		etMutex_enter(&m_mutex);
		wait = !m_terminateServices.empty();
		etMutex_leave(&m_mutex);

		if(wait)
			etSema_waitForWakeup(&m_terminateSema);
	}
}

void MessageServiceController::resetAll() {
	stop();
	etMutex_enter(&m_mutex);
	m_messageServices.clear();
	while (!m_freeIDs.empty()) {
		m_freeIDs.pop();
	}
	m_nextFreeID = 0;
	etMutex_leave(&m_mutex);
}

void MessageServiceController::setMsgSvcTerminated(const IMessageService& msgSvc){
	etMutex_enter(&m_mutex);
	std::vector<IMessageService*>::iterator it = std::find(m_terminateServices.begin(), m_terminateServices.end(), &msgSvc);
	if (it!=m_terminateServices.end()) {
		m_terminateServices.erase(it);
	}
	etSema_wakeup(&m_terminateSema);
	etMutex_leave(&m_mutex);
}

} /* namespace etRuntime */

Back to the top