src/libYARP_OS/src/Port.cpp
void _strange_select::Body ()
{
	ACE_DEBUG ((LM_DEBUG, "***** _strange_select::Body : starting\n"));

#if defined(__QNX6__) || defined(__LINUX__)
	signal (SIGCHLD, SIG_IGN);
	signal (SIGPIPE, SIG_IGN);
#endif

	OutputTarget *target, *next;

	while (!IsTerminated())
	{
		_ready_to_go.Wait ();
		
		/// hopefully in wait on the sema, it returns from here.
		if (IsTerminated()) continue;

		/// access to targets must be protected, in case, the port
		/// thread decides to delete a link ;)
		/// this should only (on average) just cause a delay in receiving
		///	a command, while operations in the port thread should take less.
		///
		_owner->list_mutex.Wait ();

		int scanned = 0;
		if (!scanned)
		{
			double now = YARPTime::GetTimeAsSeconds ();
			target = _owner->targets.GetRoot ();
			while (target != NULL)
			{
				next = target->GetMeshNext ();

				target->WaitMutex ();
				
				int active = target->active;
				int deactivated = target->deactivated;
				int ticking = target->ticking;
				double started = target->check_tick;
				
				target->PostMutex ();
				
				int timeout = 0;
				
				if (ticking && now - started > 5)
				{
					active = 0;
					timeout = 1;
					YARP_DBG(THIS_DBG) ((LM_DEBUG, "timeout expired %f\n", now-started));
				}

				if (!active)
				{
					ACE_DEBUG ((LM_INFO, "*** disconnecting %s and %s %s%s\n",
						_owner->name.c_str(), target->GetLabel().c_str(),
						deactivated ? "" : "(target stopped responding)",
						timeout?" (timeout)":""));

					delete target;
				}
				
				target = next;
			}
			scanned = 1;
		}

		// Send message to all listeners
		if (!scanned)
		{
			target = _owner->targets.GetRoot ();
			while (target != NULL)
			{
				next = target->GetMeshNext ();
				
				target->WaitMutex ();
				int active = target->active;
				int deactivated = target->deactivated;
				target->PostMutex ();

				if (!active)
				{
					ACE_DEBUG ((LM_INFO, "*** disconnecting %s and %s %s\n", 
						_owner->name.c_str(), target->GetLabel().c_str(),
						deactivated ? "" : "(target stopped responding)"));

					delete target;
				}
				target = next;
			}
		}

		YARP_DBG(THIS_DBG) ((LM_DEBUG, "Sending a message from %s\n", _owner->name.c_str()));
		target = _owner->targets.GetRoot ();

		_owner->out_mutex.Wait ();

		while (target!=NULL)
		{
			YARP_DBG(THIS_DBG) ((LM_DEBUG, "Sending a message from %s to target %s\n", _owner->name.c_str(), target->GetLabel().c_str()));
			if (_owner->p_sendable.Ptr() != NULL)
			{
				if (_owner->require_complete_send)
				{
					target->space_available.Wait ();
					target->space_available.Post ();
				}

				target->Share (_owner->p_sendable.Ptr());
				target->add_header = _owner->add_header;
			}
			else
			{
				ACE_DEBUG ((LM_DEBUG, "Delayed message skipped\n"));
			}
			
			target = target->GetMeshNext ();
		}

		/// releases the list only here
		/// 
		_owner->p_sendable.Reset ();
		
		_owner->out_mutex.Post ();
		_owner->pending = 0;
		_owner->okay_to_send.Post ();

		_owner->list_mutex.Post ();

	}	/// while !IsTerminated()

	/// 
	ACE_DEBUG ((LM_DEBUG, "***** _strange_select::Body : closing 0x%x\n", GetIdentifier()));
	_owner = NULL;
}
///
///
///
/// hopefully an improvement. a thread that handles the fact that we can't wake up
/// Port::Body both on a socket and a mutex/semaphore.
///
/// this thread takes care of sending stuff to the list of output threads. 
/// it is simply activated by the Share method instead of the MSG_ID_GO command.
///
///
hopefully an improvement. a thread that handles the fact that we can't wake up
Port::Body both on a socket and a mutex/semaphore.

this thread takes care of sending stuff to the list of output threads.
it is simply activated by the Share method instead of the MSG_ID_GO command.
hopefully an improvement . a thread that handles the fact that we can ' t wake up Port :: Body both on a socket and a mutex / semaphore . this thread takes care of sending stuff to the list of output threads . it is simply activated by the Share method instead of the MSG_ID_GO command .
void _strange_select::Body ()
{
	ACE_DEBUG ((LM_DEBUG, "***** _strange_select::Body : starting\n"));
#if defined(__QNX6__) || defined(__LINUX__)
	signal (SIGCHLD, SIG_IGN);
	signal (SIGPIPE, SIG_IGN);
#endif
	OutputTarget *target, *next;
	while (!IsTerminated())
	{
		_ready_to_go.Wait ();
		if (IsTerminated()) continue;
		_owner->list_mutex.Wait ();
		int scanned = 0;
		if (!scanned)
		{
			double now = YARPTime::GetTimeAsSeconds ();
			target = _owner->targets.GetRoot ();
			while (target != NULL)
			{
				next = target->GetMeshNext ();
				target->WaitMutex ();
				int active = target->active;
				int deactivated = target->deactivated;
				int ticking = target->ticking;
				double started = target->check_tick;
				target->PostMutex ();
				int timeout = 0;
				if (ticking && now - started > 5)
				{
					active = 0;
					timeout = 1;
					YARP_DBG(THIS_DBG) ((LM_DEBUG, "timeout expired %f\n", now-started));
				}
				if (!active)
				{
					ACE_DEBUG ((LM_INFO, "*** disconnecting %s and %s %s%s\n",
						_owner->name.c_str(), target->GetLabel().c_str(),
						deactivated ? "" : "(target stopped responding)",
						timeout?" (timeout)":""));
					delete target;
				}
				target = next;
			}
			scanned = 1;
		}
		if (!scanned)
		{
			target = _owner->targets.GetRoot ();
			while (target != NULL)
			{
				next = target->GetMeshNext ();
				target->WaitMutex ();
				int active = target->active;
				int deactivated = target->deactivated;
				target->PostMutex ();
				if (!active)
				{
					ACE_DEBUG ((LM_INFO, "*** disconnecting %s and %s %s\n", 
						_owner->name.c_str(), target->GetLabel().c_str(),
						deactivated ? "" : "(target stopped responding)"));
					delete target;
				}
				target = next;
			}
		}
		YARP_DBG(THIS_DBG) ((LM_DEBUG, "Sending a message from %s\n", _owner->name.c_str()));
		target = _owner->targets.GetRoot ();
		_owner->out_mutex.Wait ();
		while (target!=NULL)
		{
			YARP_DBG(THIS_DBG) ((LM_DEBUG, "Sending a message from %s to target %s\n", _owner->name.c_str(), target->GetLabel().c_str()));
			if (_owner->p_sendable.Ptr() != NULL)
			{
				if (_owner->require_complete_send)
				{
					target->space_available.Wait ();
					target->space_available.Post ();
				}
				target->Share (_owner->p_sendable.Ptr());
				target->add_header = _owner->add_header;
			}
			else
			{
				ACE_DEBUG ((LM_DEBUG, "Delayed message skipped\n"));
			}
			target = target->GetMeshNext ();
		}
		 releases the list only here
		_owner->p_sendable.Reset ();
		_owner->out_mutex.Post ();
		_owner->pending = 0;
		_owner->okay_to_send.Post ();
		_owner->list_mutex.Post ();
	}	 while !IsTerminated()
	ACE_DEBUG ((LM_DEBUG, "***** _strange_select::Body : closing 0x%x\n", GetIdentifier()));
	_owner = NULL;
}
void _strange_select :: Body ( ) { ACE_DEBUG ( ( LM_DEBUG , " \n " ) ) ; #if defined ( __QNX6__ ) || defined ( __LINUX__ ) signal ( SIGCHLD , SIG_IGN ) ; signal ( SIGPIPE , SIG_IGN ) ; #endif OutputTarget * target , * next ; while ( ! IsTerminated ( ) ) { _ready_to_go . Wait ( ) ; if ( IsTerminated ( ) ) continue ; _owner -> list_mutex . Wait ( ) ; int scanned = 0 ; if ( ! scanned ) { double now = YARPTime :: GetTimeAsSeconds ( ) ; target = _owner -> targets . GetRoot ( ) ; while ( target != NULL ) { next = target -> GetMeshNext ( ) ; target -> WaitMutex ( ) ; int active = target -> active ; int deactivated = target -> deactivated ; int ticking = target -> ticking ; double started = target -> check_tick ; target -> PostMutex ( ) ; int timeout = 0 ; if ( ticking && now - started > 5 ) { active = 0 ; timeout = 1 ; YARP_DBG ( THIS_DBG ) ( ( LM_DEBUG , " \n " , now - started ) ) ; } if ( ! active ) { ACE_DEBUG ( ( LM_INFO , " \n " , _owner -> name . c_str ( ) , target -> GetLabel ( ) . c_str ( ) , deactivated ? " " : " " , timeout ? " " : " " ) ) ; delete target ; } target = next ; } scanned = 1 ; } if ( ! scanned ) { target = _owner -> targets . GetRoot ( ) ; while ( target != NULL ) { next = target -> GetMeshNext ( ) ; target -> WaitMutex ( ) ; int active = target -> active ; int deactivated = target -> deactivated ; target -> PostMutex ( ) ; if ( ! active ) { ACE_DEBUG ( ( LM_INFO , " \n " , _owner -> name . c_str ( ) , target -> GetLabel ( ) . c_str ( ) , deactivated ? " " : " " ) ) ; delete target ; } target = next ; } } YARP_DBG ( THIS_DBG ) ( ( LM_DEBUG , " \n " , _owner -> name . c_str ( ) ) ) ; target = _owner -> targets . GetRoot ( ) ; _owner -> out_mutex . Wait ( ) ; while ( target != NULL ) { YARP_DBG ( THIS_DBG ) ( ( LM_DEBUG , " \n " , _owner -> name . c_str ( ) , target -> GetLabel ( ) . c_str ( ) ) ) ; if ( _owner -> p_sendable . Ptr ( ) != NULL ) { if ( _owner -> require_complete_send ) { target -> space_available . Wait ( ) ; target -> space_available . Post ( ) ; } target -> Share ( _owner -> p_sendable . Ptr ( ) ) ; target -> add_header = _owner -> add_header ; } else { ACE_DEBUG ( ( LM_DEBUG , " \n " ) ) ; } target = target -> GetMeshNext ( ) ; } _owner -> p_sendable . Reset ( ) ; _owner -> out_mutex . Post ( ) ; _owner -> pending = 0 ; _owner -> okay_to_send . Post ( ) ; _owner -> list_mutex . Post ( ) ; } ACE_DEBUG ( ( LM_DEBUG , " \n " , GetIdentifier ( ) ) ) ; _owner = NULL ; }
hopefully an improvement.
hopefully an improvement .
/// hopefully in wait on the sema, it returns from here. /// access to targets must be protected, in case, the port /// thread decides to delete a link ;) /// this should only (on average) just cause a delay in receiving ///	a command, while operations in the port thread should take less. /// // Send message to all listeners /// releases the list only here ///  /// while !IsTerminated() /// 