std::vector<gadget::NodePtr> Reactor::getReadyNodes(const vpr::Interval& timeout) { vpr::Uint16 num_events(0); mSelector.select(num_events, timeout); std::vector<gadget::NodePtr> ready_nodes; if ( num_events > 0 ) { ready_nodes.reserve(num_events); vpr::Uint16 event_mask; const vpr::Uint16 num_handles = mSelector.getNumHandles(); for ( vpr::Uint16 i = 0; i < num_handles; ++i ) { vpr::IOSys::Handle h = mSelector.getHandle(i); event_mask = mSelector.getOut(h); if ( 0 != event_mask ) { ready_nodes.push_back(mDemuxTable[h]); } } } return ready_nodes; }
void CKeySendImpl::NewSendChar(TCHAR c) { UINT status; INPUT input[4] = {cinput, cinput, cinput, cinput}; UINT num_events(2); bool tabWait = false; // if sending tab\newline, wait a bit after send // for the dust to settle. Thanks to Larry... switch (c) { case L'\t': case L'\r': /* For Tab or Carriage Return equivalent to: keybd_event(VK_TAB or VK_RETURN, 0, 0, 0); keybd_event(VK_TAB or VK_RETURN, 0, KEYEVENTF_KEYUP, 0); */ input[0].ki.wVk = input[1].ki.wVk = (c == L'\t') ? VK_TAB : VK_RETURN; input[1].ki.dwFlags = KEYEVENTF_KEYUP; tabWait = true; break; case L'\v': /* Special case for Shift+Tab equivalent to: (assumes Shift key is not down to start! keybd_event(VK_SHIFT, 0, 0, 0); keybd_event(VK_TAB, 0, 0, 0); keybd_event(VK_TAB, 0, KEYEVENTF_KEYUP, 0); keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0); */ num_events = 4; input[0].ki.wVk = input[3].ki.wVk = VK_SHIFT; input[1].ki.wVk = input[2].ki.wVk = VK_TAB; input[2].ki.dwFlags = KEYEVENTF_KEYUP; input[3].ki.dwFlags = KEYEVENTF_KEYUP; tabWait = true; break; default: /* For all others equivalent to: keybd_event(0, c, KEYEVENTF_UNICODE, 0); keybd_event(0, c, KEYEVENTF_UNICODE | KEYEVENTF_KEYUP, 0); */ input[0].ki.wScan = input[1].ki.wScan = c; input[0].ki.dwFlags = KEYEVENTF_UNICODE; input[1].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; break; } status = ::SendInput(num_events, input, sizeof(INPUT)); if (status != num_events) pws_os::Trace(L"CKeySend::SendChar: SendInput failed status=%d\n", status); // wait at least 200 ms if we just sent a tab, regardless of m_delay int delay = (m_delay < 200 && tabWait) ? 200 : m_delay; ::Sleep(delay); }
// Idea: // - If have read or write and there are no socket errors, then we are // connected bool SocketImplBSD::isConnected() const { if ( isOpen() && mConnectCalled ) { //vpr::Int32 bytes; bool readable = mHandle->isReadable(vpr::Interval::NoWait); bool writable = mHandle->isWriteable(vpr::Interval::NoWait); boost::ignore_unused_variable_warning(readable); boost::ignore_unused_variable_warning(writable); try { SelectorImplBSD selector; selector.addHandle(getHandle(), SelectorBase::Read | SelectorBase::Write); vpr::Uint16 num_events(0); selector.select(num_events, vpr::Interval::NoWait); } catch(TimeoutException& te) { return false; } vpr::SocketOptions::Data opt_data; getOption(SocketOptions::Error, opt_data); int sock_error = opt_data.error; if(sock_error) { //close(); buildAndThrowException("[vpr::SocketImplBSD::isConnected()] Error: ", VPR_LOCATION, sock_error); } // No error, so we are connected return true; } return false; }
// Connect the socket on the client side to the server side. For a datagram // socket, this makes the address given to the constructor the default // destination for all packets. For a stream socket, this has the effect of // establishing a connection with the destination. void SocketImplBSD::connect(vpr::Interval timeout) { int status; // Attempt to connect to the address in mAddr. status = ::connect(mHandle->mFdesc, (struct sockaddr*) &mRemoteAddr.mAddr, mRemoteAddr.size()); // If connect(2) failed, print an error message explaining why and return // error status. if ( status == -1 ) { // If this is a non-blocking connection, return normally with the // post condition that users must call isConnected() after calling // connect when using non-blocking sockets. // NOTE: I'm not sure if it's safe to set mConnectCalled and // mBlockingFixed at this point, but they have to be set sometime. if ( errno == EINPROGRESS && ! isBlocking() ) { if ( vpr::Interval::NoWait != timeout ) { // Force socket to wait for timeout interval to expire // before returning. This provides a way for the caller // to specify that they want the connection process to // block even with a non-blocking socket. try { // Wait for read/write on the socket SelectorImplBSD selector; selector.addHandle(getHandle(), SelectorBase::Read | SelectorBase::Write); vpr::Uint16 num_events(0); selector.select(num_events, timeout); // Check for error state on socket vpr::SocketOptions::Data opt_data; getOption(SocketOptions::Error, opt_data); int sock_error = opt_data.error; if ( sock_error ) { close(); buildAndThrowException( "[vpr::SocketImplBSD::connect()] Async-connection error: ", VPR_LOCATION, sock_error ); } else // Completed in time { mBound = true; mConnectCalled = true; mBlockingFixed = true; } } // Select timed out, so the connect timed out catch (TimeoutException& te) { close(); throw TimeoutException("Timeout while connecting.", VPR_LOCATION); } } else // non-blocking connect started { mBound = true; mConnectCalled = true; mBlockingFixed = true; } } else { buildAndThrowException("[vpr::SocketImplBSD::connect()] ", VPR_LOCATION); } } // Otherwise, return success. else { mBound = true; mConnectCalled = true; mBlockingFixed = true; } // Fill in the local address if has not already been assigned. if ( mConnectCalled && vpr::InetAddr::AnyAddr == mLocalAddr ) { int status; #if defined(VPR_OS_IRIX) || defined(VPR_OS_HPUX) int namelen; #else socklen_t namelen; #endif struct sockaddr temp_addr; namelen = sizeof(struct sockaddr); status = getsockname(mHandle->mFdesc, &temp_addr, &namelen); if ( status == 0 ) { mLocalAddr.setSockaddr(&temp_addr); /* XXX: This doesn't compile on IRIX, and I don't know why. vprDEBUG(vprDBG_ALL, vprDBG_STATE_LVL) << "Connected, local address is " << mLocalAddr << std::endl << vprDEBUG_FLUSH; */ } else { vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL) << "Failed to get sock name: " << strerror(errno) << std::endl << vprDEBUG_FLUSH; } } }