SignalSet SignalInformationQueue::getQueuedSignalSet() const
{
	SignalSet queuedSignalSet {SignalSet::empty};
	for (const auto& node : signalInformationList_)
		queuedSignalSet.add(node.signalInformation.getSignalNumber());
	return queuedSignalSet;
}
bool signalsTestSelfOneSignalPending(const uint8_t signalNumber)
{
	SignalSet expectedSignalSet {SignalSet::empty};
	if (expectedSignalSet.add(signalNumber) != 0)
		return false;

	return ThisThread::Signals::getPendingSignalSet().getBitset() == expectedSignalSet.getBitset();
}
std::pair<int, SignalAction> SignalsCatcherControlBlock::setAssociation(const uint8_t signalNumber,
		const SignalAction& signalAction)
{
	if (signalNumber >= SignalSet::Bitset{}.size())
		return {EINVAL, {}};

	if (signalAction.getHandler() == SignalAction{}.getHandler())	// default handler is being set?
	{
		const auto previousSignalAction = clearAssociation(signalNumber);
		return {{}, previousSignalAction};
	}

	const auto numberAssociation = findAssociation(associationsBegin_, associationsEnd_, signalNumber);
	const auto actionAssociation = findAssociation(associationsBegin_, associationsEnd_, signalAction);

	if (actionAssociation != associationsEnd_)	// there is an association for this SignalAction?
	{
		if (numberAssociation == actionAssociation)	// no change?
			return {{}, signalAction};

		actionAssociation->first.add(signalNumber);
		const auto previousSignalAction = numberAssociation != associationsEnd_ ?
				clearAssociation(signalNumber, *numberAssociation) : SignalAction{};
		return {{}, previousSignalAction};
	}

	// there is no association for this SignalAction?

	SignalSet signalSet {1u << signalNumber};

	// there is no storage for new association if all conditions are true:
	// - there are no free associations,
	// - no Association object was found for signal number or Association object found for signal number has more
	// than one signal number associated.
	if (std::distance(storageBegin_, storageEnd_) == 0 && (numberAssociation == associationsEnd_ ||
			numberAssociation->first.getBitset() != signalSet.getBitset()))
		return {EAGAIN, {}};

	const auto previousSignalAction = numberAssociation != associationsEnd_ ?
			clearAssociation(signalNumber, *numberAssociation) : SignalAction{};
	if (storageBegin_ == storageEnd_)
		abort();	/// \todo replace with assertion
	new (associationsEnd_) Association{signalSet, signalAction};
	++associationsEnd_;
	return {{}, previousSignalAction};
}
Example #4
0
        SignalDispatcher(const Args&... args)
            : _signal_set(_io_service, SIGINT, SIGTERM)
            , _thread(new std::thread(std::bind((IoServiceRunFunc)&IoService::run, &_io_service)))
        {
            std::size_t size = sizeof...(args);
            StopHandle res[sizeof...(args)] = {args...};

            auto stop_func = [size, res] () {
                for (std::uint32_t i = 0; i < size; ++i) {
                    res[i]();
                }
                LOG(INFO) << "Stop modules.";
            };
            _signal_set.async_wait(std::bind(stop_func));
            _thread->join();
        }
void
SignalThread::run_(const SignalSet& sigset)
{
    // boost::asio has support for signals via signal_set. It does however not
    // accept a sigset_t and neither can a sigset_t nor a ba::signal_set be inspected.

    int sigfd = signalfd(-1,
                         &sigset.sigset(),
                         SFD_NONBLOCK);
    if (sigfd < 0)
    {
        LOG_ERROR("Failed to create signalfd: " << strerror(errno));
        throw Exception("Failed to create signalfd");
    }

    auto exit(make_scope_exit([&]
                              {
                                  close(sigfd);
                              }));

    std::function<void()> g;

    auto f([&](const bs::error_code& ec,
               std::size_t bytes)
           {
               VERIFY(bytes == 0);

               if (ec)
               {
                   LOG_ERROR("error in signal handler: " <<
                             ec.message());
               }
               else
               {
                   signalfd_siginfo si;
                   ssize_t ret = ::read(sigfd,
                                        &si,
                                        sizeof(si));
                   if (ret < 0)
                   {
                       if (ret != EAGAIN)
                       {
                           ret = errno;
                           LOG_ERROR("failed to read siginfo from signalfd: " <<
                                     strerror(ret) << " (" << ret << ")");
                       }
                       g();
                   }
                   else if (ret != sizeof(si))
                   {
                       LOG_ERROR("read less (" << ret << " ) than expected (" <<
                                 sizeof(si) << ") from signalfd");
                   }
                   else
                   {
                       LOG_INFO("caught signal " << si.ssi_signo);
                       handler_(si.ssi_signo);
                       g();
                   }
               }
           });

    ba::posix::stream_descriptor sigdesc(io_service_,
                                         sigfd);

    g = [&]()
        {
            sigdesc.async_read_some(ba::null_buffers(),
                                    f);
        };

    g();

    bs::error_code ec;
    io_service_.run(ec);

    if (ec)
    {
        LOG_ERROR("error running I/O service of signal thread: " <<
                  ec.message());
    };

    LOG_INFO("exiting signal handler thread");
}
void TrueTimeSourceVisitor::Visit_QualifiedMessageStructure( const QualifiedMessage & qualifiedMessage, 
													   const Semantics::Task & task ) {
	// Get the actual message object
	Semantics::Msg message = qualifiedMessage.message;
	// Create a new section for it
	AddSectionDictionary( "MESSAGE_SECTION" );
	// Get the message name
	std::string messageName = message.name();
	// Figure out non-dotted name
	string::size_type pos = messageName.find(".");
	if ( pos != string::npos )
		messageName.replace( pos, 1, "_" );
	DEBUGOUT( "\tMessage: " << messageName << std::endl );

	std::string messageType = message.messagetype();
	GetTemplateDictionary().SetValue( "MESSAGE_NAME", messageName );

	// Get the associated signals
	SignalSet signalSet = message.carries();
	SignalSet::iterator signalIter = signalSet.begin();

	SortedSignal_ByMsgIndex_Set filteredSignalSet;

	// Loop through all signals
	for( ; signalIter != signalSet.end() ; signalIter++ ) {
		std::string signalName = signalIter->name();
		ComponentSet receivingComponentSet = signalIter->consumedBy();
		Semantics::Component transmittingComponent = signalIter->generatedBy();
		// Check to make sure for something?!?!?!?!?
		if ( qualifiedMessage.type == TRANSMIT && receivingComponentSet.empty() ||
			 qualifiedMessage.type == RECEIVE && transmittingComponent == Udm::null ||
			 qualifiedMessage.type == PERIPHERAL ) {
				// Insert the signal into the sorted set
				filteredSignalSet.insert( *signalIter );
		}
	}

	// Use the constructed sorted signal set to fill in the template
	SortedSignal_ByMsgIndex_Set::iterator filteredSignalIter = filteredSignalSet.begin();
	for ( ; filteredSignalIter != filteredSignalSet.end(); filteredSignalIter++ ) {
		Visit_Signal_Member( *filteredSignalIter );
	}

	// Finish up with this section
	PopSectionDictionary();

	// See if message is remote
	if ( messageType.compare( "Remote" ) == 0 ) {

		Semantics::CommMedium cm = GetMessageBus( message );
		string busName = "bus";
		if ( cm != Udm::null )
		{
			busName = cm.name();
		}

		AddSectionDictionary( "BUSMESSAGE_SECTION" );
		string msgTaskName = messageName + "_task";
		GetTemplateDictionary().SetValue( "BUSMESSAGE_NAME", msgTaskName );
		GetTemplateDictionary().SetValue( "BUSMESSAGE_FULLNAME", messageName );
		GetTemplateDictionary().SetValue( "BUSMESSAGE_FUNCTION", messageName + "_code" );
		// Get the exec info and schedule
		ExecInfoSet execInfoSet = message.info();
		ExecInfoSet::iterator execInfoIter = execInfoSet.begin();
		Semantics::Duration duration = execInfoIter->Duration_child();
		double wcet = duration.exectimesecs();
		string wcet_symbol = msgTaskName + "_WCET";
		ostringstream out1;
		out1 << "#define " << wcet_symbol << " " << wcet;
		_BusHeaderLines[busName].insert( out1.str() );

		GetTemplateDictionary().SetValue( "BUSMESSAGE_WCET_STR", wcet_symbol );
		GetTemplateDictionary().SetFormattedValue( "BUSMESSAGE_WCET", "%f", wcet );
		// Setup the peripheral schedule
		Semantics::Schedule schedule = execInfoIter->Schedule_child();
		std::string sched = schedule.sched();
		int count = sched_count( sched );
		vector< double > start_times = sched_values( sched );
		ostringstream symbolic_array;
		for ( int idx = 0; idx < count; idx++ )
		{
			ostringstream out2;
			out2 << "#define " << msgTaskName << "_" << idx << " " << start_times[idx];
			_BusHeaderLines[busName].insert( out2.str() );
			if ( idx > 0 )
			{
				symbolic_array << ", ";
			}
			symbolic_array << msgTaskName << "_" << idx;
		}


		GetTemplateDictionary().SetIntValue( "BUSMESSAGE_COUNT", count );
		GetTemplateDictionary().SetValue( "BUSMESSAGE_SCHEDULE", symbolic_array.str() );

		// Get the network that transmits the message
		ReceivesSet receiveSet = message.msgListeners();
		// TODO: Need to figure out how to disambiguate receivers for this message
		Semantics::BChan bChan = receiveSet.begin()->receivingChannel();
		Semantics::CommInterface commInterface = bChan.chanInterface();
		Semantics::CommMedium network = commInterface.commMedium();
		// Find the network in the map
		std::map< std::string, TTNetwork >::const_iterator mapIter = _networkMap.find( network.name() );
		// Setup the message handling code
		Semantics::Transmits transmitter = message.msgTransmitter();
		Semantics::Task sendingTask = transmitter.sendingTask();
		// See if this task is being sent or received
		if ( sendingTask == task ) {
			// Add the appropriate section
			AddSectionDictionary( "BUSMESSAGE_SEND" );
			// Loop on all receivers
			ReceivesSet::iterator receivesIter = receiveSet.begin();
			for ( ; receivesIter != receiveSet.end(); receivesIter++ ) {
				AddSectionDictionary( "BUSMESSAGE_SENDBLOCK" );
				// Which node is receiving
				Semantics::Task task = receivesIter->receivingTask();
				Semantics::Node node = task.executedBy();
				// Find the node in the mapIter
				std::map< std::string, int >::iterator nodeIter = mapIter->second.nodes->find( node.name() );
				// Set the network
				GetTemplateDictionary().SetIntValue( "BUSMESSAGE_NETWORK", mapIter->second.id );
				// Set the receiver
				GetTemplateDictionary().SetIntValue( "BUSMESSAGE_RECEIVER", nodeIter->second );
				// Done with this send block
				PopSectionDictionary();
			}
			// Done with the BUSMESSAGE_SEND
			PopSectionDictionary();
		}
		// Must be receiving
		else {
			// Add the appropriate section
			AddSectionDictionary( "BUSMESSAGE_RECEIVE" );
			// Set the network ID
			GetTemplateDictionary().SetIntValue( "BUSMESSAGE_NETWORK", mapIter->second.id );
			// Done with this section
			PopSectionDictionary();
		}
		PopSectionDictionary();
	}
}