Esempio n. 1
0
int
main()
{
	JTCInitialize boot_jtc;

	try
	{
		//
		// TEST: Verify notify() or notifyAll() occur when wait() is
		// called.
		//
		JTCHandleT<TestThread> t = new TestThread;
		t -> start();

		//
		// Wait for the thread to start
		//
		t -> wait_start();

		//
		// Notify the thread. Note that the monitor cannot be notified
		// until the lock is obtained which should mean that the
		// monitor is already waiting.
		//
		{
			JTCSynchronized sync(*t);
			t -> notify();
		}

		while (t -> isAlive())
		{
			try
			{
				t -> join();
			}
			catch(const JTCInterruptedException&)
			{
			}
		}

		//
		// TEST: Verify that one call to notify() will take one
		// thread (not two!)
		//
		JTCMonitor mon;
		JTCHandleT<WaitThread> t1 = new WaitThread(mon);
		JTCHandleT<WaitThread> t2 = new WaitThread(mon);
		t1 -> start();
		t2 -> start();

		//
		// Wait until the threads enter wait().
		//
		JTCThread::sleep(1000);

		{
			JTCSynchronized sync(mon);
			mon.notify();
		}

		//
		// Sleep a second.  Either t1 or t2 might can stop -- but not
		// both.
		//
		JTCThread::sleep(1000);
		assert((t1 -> isAlive() && !t2 -> isAlive()) ||
			(t2 -> isAlive() && !t1 -> isAlive()));

		{
			JTCSynchronized sync(mon);
			mon.notify();
		}

		while (t1 -> isAlive() || t2 -> isAlive())
		{
			try
			{
				t1 -> join();
			}
			catch(const JTCInterruptedException&)
			{
			}
		}

		while (t2 -> isAlive())
		{
			try
			{
				t2 -> join();
			}
			catch(const JTCInterruptedException&)
			{
			}
		}

		//
		// TEST: Verify that two calls to notify() will take two
		// threads.
		//
		t1 = new WaitThread(mon);
		t2 = new WaitThread(mon);
		t1 -> start();
		t2 -> start();

		//
		// Wait until the threads enter wait().
		//
		JTCThread::sleep(1000);

		{
			JTCSynchronized sync(mon);
			mon.notify();
			mon.notify();
		}

		while (t1 -> isAlive())
		{
			try
			{
				t1 -> join();
			}
			catch(const JTCInterruptedException&)
			{
			}
		}
		while (t2 -> isAlive())
		{
			try
			{
				t2 -> join();
			}
			catch(const JTCInterruptedException&)
			{
			}
		}

		//
		// TEST: Verify that a call to notifyAll() will take two
		// threads.
		//
		t1 = new WaitThread(mon);
		t2 = new WaitThread(mon);
		t1 -> start();
		t2 -> start();

		//
		// Wait until the threads enter wait().
		//
		JTCThread::sleep(1000);

		{
			JTCSynchronized sync(mon);
			mon.notifyAll();
		}

		while (t1 -> isAlive())
		{
			try
			{
				t1 -> join();
			}
			catch(const JTCInterruptedException&)
			{
			}
		}
		while (t2 -> isAlive())
		{
			try
			{
				t2 -> join();
			}
			catch(const JTCInterruptedException&)
			{
			}
		}

		//
		// TEST: Verify that a call to notifyAll() actually wakes both
		// threads.
		//
		int count = 1000;
		JTCHandleT<WaitThread2> wt1 = new WaitThread2(mon, count);
		JTCHandleT<WaitThread2> wt2 = new WaitThread2(mon, count);
		wt1 -> start();
		wt2 -> start();

		//
		// Wait until the threads enter wait().
		//
		JTCThread::sleep(1000);

		while (count > 0)
		{
			JTCSynchronized sync(mon);
			wt1 -> consume();
			wt2 -> consume();
			mon.notifyAll();
			--count;
		}
		while (wt1 -> isAlive())
		{
			try
			{
				wt1 -> join();
			}
			catch(const JTCInterruptedException&)
			{
			}
		}
		while (wt2 -> isAlive())
		{
			try
			{
				wt2 -> join();
			}
			catch(const JTCInterruptedException&)
			{
			}
		}
	}
	catch(const JTCException& e)
	{
		cout << "Test failed: " << e.getMessage() << endl;
		return EXIT_FAILURE;
	}

	cout << "Test successful." << endl;
	return EXIT_SUCCESS;
}
Esempio n. 2
0
bool CTunnelingConnection::HandleTunnelRequest(unsigned char* buffer, int len, CCemi_L_Data_Frame &frame)
{
	JTCSynchronized s(*this);
	
	CTunnelingRequest req(buffer);

	if(req.GetChannelId() != _state._channelid){
		//error
		LOG_ERROR("[Received] [BUS] CEMI frame with invalid channel id. [ignored]");
		return false;
	}

	if(req.GetSequenceNumber() == _state._recv_sequence ||
		req.GetSequenceNumber() + 1 == _state._recv_sequence)
	{
		if(req.GetSequenceNumber() == _state._recv_sequence){
			_num_out_of_sync_pkts = 0;
			const CCemi_L_Data_Frame& tmpfrm = req.GetcEMI();
			LOG_DEBUG("[Received] [BUS] [Tunnel request] Sequence: %d Dest Address: %s",req.GetSequenceNumber(),
					tmpfrm.GetDestAddress().ToString().GetBuffer());
		}else{
			LOG_ERROR("[Received] [BUS] [Tunnel request] Packet has invalid sequence number (%d). [sending ack but ignoring frame]",req.GetSequenceNumber());
		}
		unsigned char buf[20];
		CTunnelingAck ack(req.GetChannelId(),req.GetSequenceNumber(),E_NO_ERROR);
		ack.FillBuffer(buf,20);
		LOG_DEBUG("[Send] [BUS] [Tunnel Ack] Sequence: %d",req.GetSequenceNumber());
		_data_sock.SendTo(buf,ack.GetTotalSize(),_device_data_address,_device_data_port);
	}else{
		_num_out_of_sync_pkts++;
		//we have many pkts out of sync consecutively
		if(_num_out_of_sync_pkts > 3){
			//we are totally out of sync. reconnect.
			LOG_ERROR("[Received] [BUS] [Tunnel request] Packet has invalid sequence number (%d). reconnecting is 3 seconds.",req.GetSequenceNumber());
			Reconnect();
		}
	}

	if(req.GetSequenceNumber() != _state._recv_sequence)
	{
		LOG_ERROR("[Received] [BUS] [Tunnel request] Packet has invalid sequence number (%d). [ignoring]",req.GetSequenceNumber());
		return false;
	}

	++_state._recv_sequence;

	unsigned char mc = req.GetcEMI().GetMessageCode();
	//Data indication
	if(mc == L_DATA_IND || mc == L_BUSMON_IND)
	{
		//data indication or bus monitor indication should be processed
		frame = req.GetcEMI();
	}
	//Data confirmation
	else if (mc == L_DATA_CON)
	{
		if(req.GetcEMI().IsPositiveConfirmation()){
			//positive confirmation was received
			frame = req.GetcEMI();
			LOG_DEBUG("[Received] [BUS] [Positive confirmation] Sequence: %d", _state._recv_sequence);
			map<int,JTCMonitor*>::iterator it = _waiting_for_confirms.find(_state._recv_sequence);
			if(it != _waiting_for_confirms.end()){
				JTCMonitor* monitor = it->second;
				JTCSynchronized s(*monitor);
				_waiting_for_confirms.erase(_state._recv_sequence);
				monitor->notify();
			}		
			return true;
		}
		else
		{
			LOG_ERROR("[Received] [BUS] [Not supported message control field in cEMI frame (negative confirmation)]");
			map<int,JTCMonitor*>::iterator it = _waiting_for_confirms.find(_state._recv_sequence);
			if(it != _waiting_for_confirms.end()){
				JTCMonitor* monitor = it->second;
				JTCSynchronized s(*monitor);
				_waiting_for_confirms.erase(_state._recv_sequence);
				monitor->notify();
			}	
			return false;
		}
	}else{
		LOG_ERROR("[Received] [BUS] [Not supported message control field in cEMI frame]");
	}

	return true;
}