示例#1
0
void ezPipeChannel_win::OnIOCompleted(IOContext* pContext, DWORD uiBytesTransfered, DWORD uiError)
{
  EZ_ASSERT_DEBUG(m_ThreadId == ezThreadUtils::GetCurrentThreadID(), "Function must be called from worker thread!");
  bool bRes = true;
  if (pContext == &m_InputState.Context)
  {
    if (!m_Connected)
    {
      if (!ProcessConnection())
        return;

      bool bHasOutput = false;
      {
        EZ_LOCK(m_OutputQueueMutex);
        bHasOutput = !m_OutputQueue.IsEmpty();
      }

      if (bHasOutput && m_OutputState.IsPending == 0)
        ProcessOutgoingMessages(0);
      if (m_InputState.IsPending)
        return;
    }
    bRes = ProcessIncomingMessages(uiBytesTransfered);
  }
  else
  {
    EZ_ASSERT_DEBUG(pContext == &m_OutputState.Context, "");
    bRes = ProcessOutgoingMessages(uiBytesTransfered);
  }
  if (!bRes && m_PipeHandle != INVALID_HANDLE_VALUE)
  {
    InternalDisconnect();
  }
}
示例#2
0
void Channel::OnIOCompleted(
    Thread::IOContext* context,
    DWORD bytes_transfered,
    DWORD error) {
  bool ok = true;
  //assert(thread_check_->CalledOnValidThread());
  if (context == &input_state_.context) {
    if (waiting_connect_) {
      if (!ProcessConnection())
        return;
      // We may have some messages queued up to send...
      if (!output_queue_.empty() && !output_state_.is_pending)
        ProcessOutgoingMessages(NULL, 0);
      if (input_state_.is_pending)
        return;
      // else, fall-through and look for incoming messages...
    }

    // We don't support recursion through OnMessageReceived yet!
	assert(!processing_incoming_);
	processing_incoming_ = true;

    // Process the new data.
    if (input_state_.is_pending) {
      // This is the normal case for everything except the initialization step.
      input_state_.is_pending = false;
      if (!bytes_transfered)
        ok = false;
      else if (pipe_ != INVALID_HANDLE_VALUE)
        ok = AsyncReadComplete(bytes_transfered);
    } else {
      assert(!bytes_transfered);
    }

    // Request more data.
    if (ok)
      ok = ProcessIncomingMessages();

	processing_incoming_ = false;
  } else {
	  assert(context == &output_state_.context);
    ok = ProcessOutgoingMessages(context, bytes_transfered);
  }
  if (!ok && INVALID_HANDLE_VALUE != pipe_) {
    // We don't want to re-enter Close().
    Close();
    listener()->OnChannelError();
  }
}
示例#3
0
void ezPipeChannel_win::InternalConnect()
{
  if (m_PipeHandle == INVALID_HANDLE_VALUE)
    return;
  if (m_Connected)
    return;
#if EZ_ENABLED(EZ_COMPILE_FOR_DEBUG)
  if (m_ThreadId == 0)
    m_ThreadId = ezThreadUtils::GetCurrentThreadID();
#endif

  if (m_Mode == Mode::Server)
  {
    ProcessConnection();
  }
  else
  {
    m_Connected = true;
  }

  if (!m_InputState.IsPending)
  {
    OnIOCompleted(&m_InputState.Context, 0, 0);
  }

  if (m_Connected)
  {
    ProcessOutgoingMessages(0);
  }

  m_Events.Broadcast(ezIpcChannelEvent(m_Mode == Mode::Client ? ezIpcChannelEvent::ConnectedToServer : ezIpcChannelEvent::ConnectedToClient, this));
  return;
}
示例#4
0
void ezPipeChannel_win::InternalSend()
{
  if (!m_OutputState.IsPending && m_Connected)
  {
    ProcessOutgoingMessages(0);
  }
}
示例#5
0
bool Channel::Connect() {
  //DLOG_IF(WARNING, thread_check_.get()) << "Connect called more than once";

  //if (!thread_check_.get())
  //  thread_check_.reset(new base::ThreadChecker());

  if (pipe_ == INVALID_HANDLE_VALUE)
    return false;

  thread_->RegisterIOHandler(pipe_, this);

  // Check to see if there is a client connected to our pipe...
  if (waiting_connect_)
    ProcessConnection();

  if (!input_state_.is_pending) {
    // Complete setup asynchronously. By not setting input_state_.is_pending
    // to true, we indicate to OnIOCompleted that this is the special
    // initialization signal.
	  thread_->PostTask(
        std::bind(&Channel::OnIOCompleted,
                   this,
                   &input_state_.context,
                   0,
                   0));
  }

  if (!waiting_connect_)
    ProcessOutgoingMessages(NULL, 0);
  return true;
}
示例#6
0
bool Channel::Send(Message* message) {
//   DCHECK(thread_check_->CalledOnValidThread());
//   DVLOG(2) << "sending message @" << message << " on channel @" << this
//            << " with type " << message->type()
//            << " (" << output_queue_.size() << " in queue)";

#ifdef IPC_MESSAGE_LOG_ENABLED
  Logging::GetInstance()->OnSendMessage(message, "");
#endif
  message->AddRef();
  //message->TraceMessageBegin();
  output_queue_.push(message);
  // ensure waiting to write
  if (!waiting_connect_) {
    if (!output_state_.is_pending) {
      if (!ProcessOutgoingMessages(NULL, 0))
        return false;
    }
  }

  return true;
}