Exemple #1
0
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;
}
Exemple #2
0
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;
      }
   }
}