// . if "forReading" is true  call callbacks registered for reading on "fd"
// . if "forReading" is false call callbacks registered for writing on "fd"
// . if fd is MAX_NUM_FDS and "forReading" is true call all sleepy callbacks
void Loop::callCallbacks_ass ( bool forReading , int fd , int64_t now , int32_t niceness ) {
	// save the g_errno to send to all callbacks
	int saved_errno = g_errno;

	ScopedLock sl(m_slotMutex);
	// get the first Slot in the chain that is waiting on this fd
	Slot *s ;
	if ( forReading ) s = m_readSlots  [ fd ];
	else              s = m_writeSlots [ fd ];
	//s = m_readSlots [ fd ];
	// ensure we called something
	int32_t numCalled = 0;

	// . now call all the callbacks
	// . most will re-register themselves (i.e. call registerCallback...()
	while ( s ) {
		// skip this slot if he has no callback
		if ( ! s->m_callback ) {
			continue;
		}

		// watch out if clock was set back
		if ( s->m_lastCall > now ) {
			s->m_lastCall = now;
		}

		// if we're a sleep callback, check to make sure not premature
		if ( fd == MAX_NUM_FDS && s->m_lastCall + s->m_tick > now ) {
			s = s->m_next;
			continue;
		}

		// skip if not a niceness match
		if ( niceness == 0 && s->m_niceness != 0 ) {
			s = s->m_next;
			continue;
		}

		// update the lastCall timestamp for this slot
		if ( fd == MAX_NUM_FDS ) {
			s->m_lastCall = now;
		}

		// do the callback

		// NOTE: callback can unregister fd for Slot s, so get next
		m_callbacksNext = s->m_next;

		logDebug( g_conf.m_logDebugLoop, "loop: enter fd callback fd=%d nice=%" PRId32, fd, s->m_niceness );

		// sanity check. -1 no longer supported
		if ( s->m_niceness < 0 ) {
			g_process.shutdownAbort(true);
		}

		m_slotMutex.unlock();
		s->m_callback ( fd , s->m_state );
		m_slotMutex.lock();

		logDebug( g_conf.m_logDebugLoop, "loop: exit fd callback fd=%" PRId32" nice=%" PRId32,
		          (int32_t)fd,(int32_t)s->m_niceness );

		// inc the flag
		numCalled++;
		// reset g_errno so all callbacks for this fd get same g_errno
		g_errno = saved_errno;
		// get the next n (will be -1 if no slot after it)
		s = m_callbacksNext;
	}

	m_callbacksNext = NULL;
}