Ejemplo n.º 1
0
StdinDataIO :: StdinDataIO(bool blocking, bool writeToStdout)
   : _stdinBlocking(blocking)
   , _writeToStdout(writeToStdout)
#ifdef USE_WIN32_STDINDATAIO_IMPLEMENTATION
   , _slaveSocketTag(0)
#else
   , _fdIO(ConstSocketRef(&_stdinSocket, false), true)
#endif
{
#ifdef USE_WIN32_STDINDATAIO_IMPLEMENTATION
   if (_stdinBlocking == false)
   {
      // For non-blocking I/O, we need to handle stdin in a separate thread. 
      // note that I freopen stdin to "nul" so that other code (read: Python)
      // won't try to muck about with stdin and interfere with StdinDataIO's
      // operation.  I don't know of any good way to restore it again after,
      // though... so a side effect of StdinDataIO under Windows is that
      // stdin gets redirected to nul... once you've created one non-blocking
      // StdinDataIO, you'll need to continue accessing stdin only via
      // non-blocking StdinDataIOs.
      bool okay = false;
      ConstSocketRef slaveSocket;
      if ((CreateConnectedSocketPair(_masterSocket, slaveSocket, false) == B_NO_ERROR)&&(SetSocketBlockingEnabled(slaveSocket, true) == B_NO_ERROR)&&(_slaveSocketsMutex.Lock() == B_NO_ERROR))
      {
         bool threadCreated = false;
         if (_stdinThreadStatus == STDIN_THREAD_STATUS_UNINITIALIZED)
         {
            DWORD junkThreadID;
#if __STDC_WANT_SECURE_LIB__
            FILE * junkFD;
#endif
            _stdinThreadStatus = ((DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE), GetCurrentProcess(), &_stdinHandle, 0, false, DUPLICATE_SAME_ACCESS))&&
#if __STDC_WANT_SECURE_LIB__
               (freopen_s(&junkFD, "nul", "r", stdin) == 0)
#else
               (freopen("nul", "r", stdin) != NULL)
#endif
               &&((_slaveThread = (::HANDLE) _beginthreadex(NULL, 0, StdinThreadEntryFunc, NULL, CREATE_SUSPENDED, (unsigned *) &junkThreadID)) != 0)) ? STDIN_THREAD_STATUS_RUNNING : STDIN_THREAD_STATUS_EXITED;
            threadCreated = (_stdinThreadStatus == STDIN_THREAD_STATUS_RUNNING);
         }
         if ((_stdinThreadStatus == STDIN_THREAD_STATUS_RUNNING)&&(_slaveSockets.Put(_slaveSocketTag = (++_slaveSocketTagCounter), slaveSocket) == B_NO_ERROR)) okay = true;
                                                                                                                                                        else LogTime(MUSCLE_LOG_ERROR, "StdinDataIO:  Could not start stdin thread!\n");
         _slaveSocketsMutex.Unlock();

         // We don't start the thread running until here, that way there's no chance of race conditions if the thread exits immediately
         if (threadCreated) ResumeThread(_slaveThread);
      }
      else LogTime(MUSCLE_LOG_ERROR, "StdinDataIO:  Error setting up I/O sockets!\n");

      if (okay == false) Close();
   }
#endif
}
Ejemplo n.º 2
0
status_t
AbstractReflectSession ::
Reconnect()
{
   TCHECKPOINT;

#ifdef MUSCLE_ENABLE_SSL
   ConstByteBufferRef publicKey;  // If it's an SSL connection we'll grab its key into here so we can reuse it
#endif

   MASSERT(IsAttachedToServer(), "Can not call Reconnect() while not attached to the server");
   if (_gateway())
   {
#ifdef MUSCLE_ENABLE_SSL
      SSLSocketDataIO * sdio = dynamic_cast<SSLSocketDataIO *>(_gateway()->GetDataIO()());
      if (sdio) publicKey = sdio->GetPublicKeyCertificate();
#endif
      _gateway()->SetDataIO(DataIORef());  // get rid of any existing socket first
      _gateway()->Reset();                 // set gateway back to its virgin state
   }

   _isConnected = _wasConnected = false;
   SetConnectingAsync(false);

   bool doTCPConnect = ((_reconnectViaTCP)&&(_asyncConnectDest.GetIPAddress() != invalidIP));
   bool isReady = false;
   ConstSocketRef sock = doTCPConnect ? ConnectAsync(_asyncConnectDest.GetIPAddress(), _asyncConnectDest.GetPort(), isReady) : CreateDefaultSocket();

   // FogBugz #5256:  If ConnectAsync() fails, we want to act as if it succeeded, so that the calling
   //                 code still uses its normal asynchronous-connect-failure code path.  That way the
   //                 caller doesn't have to worry about synchronous failure as a separate case.
   if ((doTCPConnect)&&(sock() == NULL))
   {
      ConstSocketRef tempSockRef;  // tempSockRef represents the closed remote end of the failed connection and is intentionally closed ASAP
      if (CreateConnectedSocketPair(sock, tempSockRef) == B_NO_ERROR) doTCPConnect = false;
   }

   if (sock())
   {
      DataIORef io = CreateDataIO(sock);
      if (io())
      {
         if (_gateway() == NULL)
         {
            _gateway = CreateGateway();
            if (_gateway() == NULL) return B_ERROR;
         }

#ifdef MUSCLE_ENABLE_SSL
         // auto-wrap the user's gateway and socket in the necessary SSL adapters!
         if ((publicKey())&&(dynamic_cast<TCPSocketDataIO *>(io()) != NULL))
         {
            SSLSocketDataIO * ssio = newnothrow SSLSocketDataIO(sock, false, false);
            if (ssio == NULL) {WARN_OUT_OF_MEMORY; return B_ERROR;}
            io.SetRef(ssio);
            if (ssio->SetPublicKeyCertificate(publicKey) != B_NO_ERROR) return B_ERROR;

            if (dynamic_cast<SSLSocketAdapterGateway *>(_gateway()) == NULL) 
            {
               _gateway.SetRef(newnothrow SSLSocketAdapterGateway(_gateway));
               if (_gateway() == NULL) return B_ERROR;
            }
         }
#endif

         _gateway()->SetDataIO(io);
         if (isReady) 
         {
            _isConnected = _wasConnected = true;
            AsyncConnectCompleted();
         }
         else 
         {
            _isConnected = false;
            SetConnectingAsync(doTCPConnect);
         }
         _scratchReconnected = true;   // tells ReflectServer not to shut down our new IO!
         return B_NO_ERROR;
      }
   }
   return B_ERROR;
}
Ejemplo n.º 3
0
ConstSocketRef SignalHandlerSession :: CreateDefaultSocket()
{
   ConstSocketRef sock;
   (void) CreateConnectedSocketPair(sock, _handlerSocket);
   return sock; 
}