[Xorp-hackers] question on some windows programming API

Ben Greear greearb at candelatech.com
Tue Sep 6 22:05:03 PDT 2011


Just in case someone has some better experience with this...

In the win_dispatcher.cc, it is calling WaitForMultipleObjects.  The
existing code that works OK just uses the retval - WAIT_OBJECT_0 object.
But, if I read the MS help pages right, that is really just the first
entry that may have events pending, and one should probably check the
rest to make sure we are not starving higher objects.

I tried changing the processing as below, but now xorp_fea stops
with no useful errors.  If anyone has any insight on how to properly
use WaitForMultipleObjects, I'm interested!

Thanks,
Ben


void
WinDispatcher::wait_and_dispatch(int ms)
{
     DWORD retval;

     //
     // Wait or sleep. Do not enter a state where APCs may be called;
     // they are not compatible with the XORP event loop.
     // If we need to fix the sleep quantum to deal with polled objects, do so.
     //
     if ((!_polled_pipes.empty()) && (ms > POLLED_INTERVAL_MS || ms < 0))
	ms = POLLED_INTERVAL_MS;
     //XLOG_WARNING("win-dispatcher, ms: %i handles-size: %i",
     //             ms, (int)(_handles.size()));

     // Seeing weird slownesses on windows..going to cap the timeout and see
     // if that helps.
     if (ms > 100)
	ms = 100;
     else if (ms < 0)
	ms = 0;

     if (_handles.empty()) {
	// We probably don't want to sleep forever with no pending waits,
	// as Win32 doesn't have the same concept of signals as UNIX does.
	XLOG_ASSERT(ms != -1);
	Sleep(ms);
	retval = WAIT_TIMEOUT;
     } else {
	retval = WaitForMultipleObjects(_handles.size(), &_handles[0],
					FALSE, ms);
     }
     //XLOG_WARNING("Done waiting, retval: %i", retval);
     _clock->advance_time();

     // Reads need to be handled first because they may come from
     // dying processes picked up by the handle poll.
     if (!_polled_pipes.empty())
	dispatch_pipe_reads();

     // The order of the if clauses here is important.
     if (retval == WAIT_FAILED) {
	DWORD lasterr = GetLastError();
	if (lasterr == ERROR_INVALID_HANDLE && !_handles.empty()) {
	    callback_bad_handle();
	} else {
	    // Programming error.
	    XLOG_FATAL("WaitForMultipleObjects(%d,%p,%d,%d) failed "
		       "with the error code %lu (%s). "
		       "Please report this error to the XORP core team.",
			_handles.empty() ? 0 : _handles.size(),
			_handles.empty() ? NULL : &_handles[0],
			FALSE, ms,
			lasterr, win_strerror(lasterr));
	}
     } else if (retval == WAIT_TIMEOUT) {
	// The timeout period elapsed. This is normal. Fall through.
     } else if (retval <= (WAIT_OBJECT_0 + _handles.size() - 1)) {
	//
	// An object in _handles was signalled. Dispatch its callback.
	// Check if it's an event associated with a socket first.
	// This is really just the first one, so try all the rest as well.
	//
	for (int i = retval - WAIT_OBJECT_0; i<(_handles.size() - WAIT_OBJECT_0); i++) {
	    HANDLE eh = _handles[i];
	    XLOG_INFO("retval: %i handle: %i  i: %i  _handles.size(): %i\n",
		      (int)(retval), (int)(eh), i, _handles.size());

	    EventSocketMap::iterator qq = _event_socket_map.find(eh);
	    if (qq != _event_socket_map.end()) {
		dispatch_sockevent(qq->first, qq->second);
	    } else {
		// It's not an Event, so it must be something else.
		// Figure out what it is, and deal with it.
		XorpFd efd(eh);
		XLOG_ASSERT(efd.type() != XorpFd::FDTYPE_SOCKET);
		XLOG_ASSERT(efd.type() != XorpFd::FDTYPE_PIPE);
		IoEventType evtype = (efd.type() == XorpFd::FDTYPE_CONSOLE) ?
		    IOT_READ : IOT_EXCEPTION;
		IoEventMap::iterator jj =
		    _callback_map.find(IoEventTuple(efd, evtype));
		if (jj != _callback_map.end()) {
		    XLOG_INFO("event: evtype: %i  efd: %s\n",
			      (int)(evtype), cstring(efd));
		    jj->second->dispatch(efd, evtype);
		    XLOG_INFO("Done with event dispatch..\n");
		} else {
		    XLOG_ERROR("no callback for object %s", efd.str().c_str());
		}
	    }
	}// for all possible events.
	XLOG_INFO("Done handling events...\n");
     } else {
	// Programming error.
	XLOG_FATAL("WaitForMultipleObjects(%d,%p,%d,%d) returned an "
		   "unhandled return value %lu. "
		   "Please report this error to the XORP core team.",
		   _handles.empty() ? 0 : _handles.size(),
		   _handles.empty() ? NULL : &_handles[0],
		   FALSE, ms, retval);
     }
}

-- 
Ben Greear <greearb at candelatech.com>
Candela Technologies Inc  http://www.candelatech.com



More information about the Xorp-hackers mailing list