コード例 #1
0
/** The main function for the background thread
 *
 * Loops until the forground thread requests it to stop.  Reads data from the
 *network,
 * parses it and stores the resulting events (and other metadata) in a temporary
 * workspace.
 */
void ISISLiveEventDataListener::run() {

  try {
    if (!m_isConnected) // sanity check
    {
      throw std::runtime_error(std::string("No connection to the DAE."));
    }

    TCPStreamEventDataNeutron events;
    while (!m_stopThread) {
      // get the header with the type of the packet
      Receive(events.head, "Events header",
              "Corrupt stream - you should reconnect.");
      if (!(events.head.type == TCPStreamEventHeader::Neutron)) {
        // don't know what to do with it - stop
        throw std::runtime_error("Unknown packet type.");
      }
      CollectJunk(events.head);

      // get the header with the sream size
      Receive(events.head_n, "Neutrons header",
              "Corrupt stream - you should reconnect.");
      CollectJunk(events.head_n);

      // absolute pulse (frame) time
      Mantid::Kernel::DateAndTime pulseTime =
          m_startTime + static_cast<double>(events.head_n.frame_time_zero);
      // Save the pulse charge in the logs
      double protons = static_cast<double>(events.head_n.protons);
      m_eventBuffer[0]
          ->mutableRun()
          .getTimeSeriesProperty<double>(PROTON_CHARGE_PROPERTY)
          ->addValue(pulseTime, protons);

      events.data.resize(events.head_n.nevents);
      uint32_t nread = 0;
      // receive the events
      while (nread < events.head_n.nevents) {
        int ntoread = m_socket.available() /
                      static_cast<int>(sizeof(TCPStreamEventNeutron));
        if (ntoread > static_cast<int>(events.head_n.nevents - nread)) {
          ntoread = static_cast<int>(events.head_n.nevents - nread);
        }
        if (ntoread > 0) {
          m_socket.receiveBytes(
              &(events.data[nread]),
              ntoread * static_cast<int>(sizeof(TCPStreamEventNeutron)));
          nread += ntoread;
        } else {
          Poco::Thread::sleep(RECV_WAIT);
        }
      }
      if (!events.isValid()) {
        throw std::runtime_error("corrupt stream - you should reconnect");
      }

      // store the events
      saveEvents(events.data, pulseTime, events.head_n.period);
    }

  } catch (std::runtime_error &
               e) { // exception handler for generic runtime exceptions

    g_log.error() << "Caught a runtime exception." << std::endl
                  << "Exception message: " << e.what() << std::endl;
    m_isConnected = false;

    m_backgroundException = boost::make_shared<std::runtime_error>(e);

  } catch (std::invalid_argument &
               e) { // TimeSeriesProperty (and possibly some other things) can
                    // can throw these errors
    g_log.error() << "Caught an invalid argument exception." << std::endl
                  << "Exception message: " << e.what() << std::endl;
    m_isConnected = false;
    std::string newMsg(
        "Invalid argument exception thrown from the background thread: ");
    newMsg += e.what();
    m_backgroundException = boost::make_shared<std::runtime_error>(newMsg);

  } catch (...) { // Default exception handler
    g_log.error() << "Uncaught exception in ISISLiveEventDataListener network "
                     "read thread." << std::endl;
    m_isConnected = false;
    m_backgroundException = boost::shared_ptr<std::runtime_error>(
        new std::runtime_error("Unknown error in backgound thread"));
  }
}
コード例 #2
0
ファイル: example.cpp プロジェクト: AlistairMills/mantid
/// connect to an event mode control progam and read live events
int liveData(const std::string& host)
{
	static char* junk_buffer[10000];
	Poco::Net::StreamSocket s;
    Poco::UInt16 port = 10000;
	Poco::Net::SocketAddress address(host, port);
	s.connect(address);
	TCPStreamEventDataSetup setup;
    while( s.available() < static_cast<int>(sizeof(setup)) )
	{
		Poco::Thread::sleep(1000);
	}
	s.receiveBytes(&setup, sizeof(setup));
	if ( !setup.isValid() )
	{
		throw std::runtime_error("version wrong");
	}
	std::cerr << "run number " << setup.head_setup.run_number << std::endl; 
	TCPStreamEventDataNeutron events;
	while(true)
	{
        while(s.available() < static_cast<int>(sizeof(events.head)))
		{
			Poco::Thread::sleep(100);
		}
		s.receiveBytes(&events.head, sizeof(events.head));
		if ( !events.head.isValid() )
		{
			throw std::runtime_error("corrupt stream - you should reconnect");
		}
		if ( !(events.head.type == TCPStreamEventHeader::Neutron) )
		{
			throw std::runtime_error("corrupt stream - you should reconnect");
		}
        s.receiveBytes(junk_buffer, events.head.length - static_cast<uint32_t>(sizeof(events.head)));
        while(s.available() < static_cast<int>(sizeof(events.head_n)))
		{
			Poco::Thread::sleep(100);
		}
		s.receiveBytes(&events.head_n, sizeof(events.head_n));
		if ( !events.head_n.isValid() )
		{
			throw std::runtime_error("corrupt stream - you should reconnect");
		}
        s.receiveBytes(junk_buffer, events.head_n.length - static_cast<uint32_t>(sizeof(events.head_n)));
        events.data.resize(events.head_n.nevents);
        uint32_t nread = 0;
		while( nread < events.head_n.nevents )
		{
      uint32_t ntoread = static_cast<uint32_t>(s.available() / static_cast<int>(sizeof(TCPStreamEventNeutron)));
			if ( ntoread > (events.head_n.nevents - nread) )
			{
				ntoread = events.head_n.nevents - nread;
			}
			if (ntoread > 0)
			{
                s.receiveBytes(&(events.data[nread]), ntoread * static_cast<int>(sizeof(TCPStreamEventNeutron)));
				nread += ntoread;
			}
			else
			{
				Poco::Thread::sleep(100);
			}
		}
		if (!events.isValid())
		{
			throw std::runtime_error("corrupt stream - you should reconnect");
		}
        //TCPStreamEventHeader& head = events.head;
		TCPStreamEventHeaderNeutron& head_n = events.head_n;
		std::cerr << "Read " << nread << " events for frame number " << head_n.frame_number << " time " << head_n.frame_time_zero << std::endl;
		for(int i=0; i<10; ++i)
		{
			std::cerr << events.data[i].time_of_flight << " " << events.data[i].spectrum << std::endl;
		}
	}
	s.close();
	return 0;
}