Beispiel #1
0
int
TCP_Transporter::doReceive(TransporterReceiveHandle& recvdata)
{
  // Select-function must return the socket for read
  // before this method is called
  // It reads the external TCP/IP interface once
  Uint32 size = receiveBuffer.sizeOfBuffer - receiveBuffer.sizeOfData;
  if(size > 0){
    const int nBytesRead = (int)my_recv(theSocket,
				receiveBuffer.insertPtr,
				size < maxReceiveSize ? size : maxReceiveSize,
				0);

    if (nBytesRead > 0) {
      receiveBuffer.sizeOfData += nBytesRead;
      receiveBuffer.insertPtr  += nBytesRead;
      
      if(receiveBuffer.sizeOfData > receiveBuffer.sizeOfBuffer){
#ifdef DEBUG_TRANSPORTER
        g_eventLogger->error("receiveBuffer.sizeOfData(%d) > receiveBuffer.sizeOfBuffer(%d)",
                             receiveBuffer.sizeOfData, receiveBuffer.sizeOfBuffer);
        g_eventLogger->error("nBytesRead = %d", nBytesRead);
#endif
        g_eventLogger->error("receiveBuffer.sizeOfData(%d) > receiveBuffer.sizeOfBuffer(%d)",
                             receiveBuffer.sizeOfData, receiveBuffer.sizeOfBuffer);
	report_error(TE_INVALID_MESSAGE_LENGTH);
	return 0;
      }
      
      receiveCount ++;
      receiveSize  += nBytesRead;
      m_bytes_received += nBytesRead;
      
      if(receiveCount == reportFreq){
        recvdata.reportReceiveLen(remoteNodeId,
                                  receiveCount, receiveSize);
	receiveCount = 0;
	receiveSize  = 0;
      }
      return nBytesRead;
    } else {
#if defined DEBUG_TRANSPORTER
      g_eventLogger->error("Receive Failure(disconnect==%d) to node = %d nBytesSent = %d "
                           "errno = %d strerror = %s",
                           DISCONNECT_ERRNO(my_socket_errno(), nBytesRead),
                           remoteNodeId, nBytesRead, my_socket_errno(),
                           (char*)ndbstrerror(my_socket_errno()));
#endif   
      if(DISCONNECT_ERRNO(my_socket_errno(), nBytesRead)){
	do_disconnect(my_socket_errno());
      } 
    }
    return nBytesRead;
  } else {
    return 0;
  }
}
Beispiel #2
0
bool
TCP_Transporter::doSend() {
  // If no sendbuffers are used nothing is done
  // Sends the contents of the SendBuffers until they are empty
  // or until select does not select the socket for write.
  // Before calling send, the socket must be selected for write
  // using "select"
  // It writes on the external TCP/IP interface until the send buffer is empty
  // and as long as write is possible (test it using select)

  // Empty the SendBuffers
  
  bool sent_any = true;
  while (m_sendBuffer.dataSize > 0)
  {
    const char * const sendPtr = m_sendBuffer.sendPtr;
    const Uint32 sizeToSend    = m_sendBuffer.sendDataSize;
    const int nBytesSent = send(theSocket, sendPtr, sizeToSend, 0);
    
    if (nBytesSent > 0) 
    {
      sent_any = true;
      m_sendBuffer.bytesSent(nBytesSent);
      
      sendCount ++;
      sendSize  += nBytesSent;
      if(sendCount == reportFreq)
      {
	reportSendLen(get_callback_obj(), remoteNodeId, sendCount, sendSize);
	sendCount = 0;
	sendSize  = 0;
      }
    } 
    else 
    {
      if (nBytesSent < 0 && InetErrno == EAGAIN && sent_any)
        break;

      // Send failed
#if defined DEBUG_TRANSPORTER
      g_eventLogger.error("Send Failure(disconnect==%d) to node = %d nBytesSent = %d "
	       "errno = %d strerror = %s",
	       DISCONNECT_ERRNO(InetErrno, nBytesSent),
	       remoteNodeId, nBytesSent, InetErrno, 
	       (char*)ndbstrerror(InetErrno));
#endif   
      if(DISCONNECT_ERRNO(InetErrno, nBytesSent)){
	doDisconnect();
	report_disconnect(InetErrno);
      }
      
      return false;
    }
  }
  return true;
}
Beispiel #3
0
int
TCP_Transporter::doReceive() {
  // Select-function must return the socket for read
  // before this method is called
  // It reads the external TCP/IP interface once
  Uint32 size = receiveBuffer.sizeOfBuffer - receiveBuffer.sizeOfData;
  if(size > 0){
    const int nBytesRead = recv(theSocket, 
				receiveBuffer.insertPtr, 
				size < maxReceiveSize ? size : maxReceiveSize, 
				0);
    
    if (nBytesRead > 0) {
      receiveBuffer.sizeOfData += nBytesRead;
      receiveBuffer.insertPtr  += nBytesRead;
      
      if(receiveBuffer.sizeOfData > receiveBuffer.sizeOfBuffer){
#ifdef DEBUG_TRANSPORTER
	ndbout_c("receiveBuffer.sizeOfData(%d) > receiveBuffer.sizeOfBuffer(%d)",
		 receiveBuffer.sizeOfData, receiveBuffer.sizeOfBuffer);
	ndbout_c("nBytesRead = %d", nBytesRead);
#endif
	ndbout_c("receiveBuffer.sizeOfData(%d) > receiveBuffer.sizeOfBuffer(%d)",
		 receiveBuffer.sizeOfData, receiveBuffer.sizeOfBuffer);
	report_error(TE_INVALID_MESSAGE_LENGTH);
	return 0;
      }
      
      receiveCount ++;
      receiveSize  += nBytesRead;
      
      if(receiveCount == reportFreq){
	reportReceiveLen(get_callback_obj(), remoteNodeId, receiveCount, receiveSize);
	receiveCount = 0;
	receiveSize  = 0;
      }
      return nBytesRead;
    } else {
#if defined DEBUG_TRANSPORTER
      ndbout_c("Receive Failure(disconnect==%d) to node = %d nBytesSent = %d "
	       "errno = %d strerror = %s",
	       DISCONNECT_ERRNO(InetErrno, nBytesRead),
	       remoteNodeId, nBytesRead, InetErrno, 
	       (char*)ndbstrerror(InetErrno));
#endif   
      if(DISCONNECT_ERRNO(InetErrno, nBytesRead)){
	// The remote node has closed down
	doDisconnect();
	report_disconnect(InetErrno);
      } 
    }
    return nBytesRead;
  } else {
    return 0;
  }
}
int
TCP_Transporter::doSend() {
  struct iovec iov[64];
  Uint32 cnt = fetch_send_iovec_data(iov, NDB_ARRAY_SIZE(iov));

  if (cnt == 0)
  {
    return 0;
  }

  Uint32 sum = 0;
  for(Uint32 i = 0; i<cnt; i++)
  {
    assert(iov[i].iov_len);
    sum += iov[i].iov_len;
  }

  Uint32 pos = 0;
  Uint32 sum_sent = 0;
  Uint32 send_cnt = 0;
  Uint32 remain = sum;

  if (cnt == NDB_ARRAY_SIZE(iov))
  {
    // If pulling all iov's make sure that we never return everyting
    // flushed
    sum++;
  }

  while (send_cnt < 5)
  {
    send_cnt++;
    Uint32 iovcnt = cnt > m_os_max_iovec ? m_os_max_iovec : cnt;
    int nBytesSent = (int)my_socket_writev(theSocket, iov+pos, iovcnt);
    assert(nBytesSent <= (int)remain);

    if (Uint32(nBytesSent) == remain)
    {
      sum_sent += nBytesSent;
      goto ok;
    }
    else if (nBytesSent > 0)
    {
      sum_sent += nBytesSent;
      remain -= nBytesSent;

      /**
       * Forward in iovec
       */
      while (Uint32(nBytesSent) >= iov[pos].iov_len)
      {
        assert(iov[pos].iov_len > 0);
        nBytesSent -= iov[pos].iov_len;
        pos++;
        cnt--;
      }

      if (nBytesSent)
      {
        assert(iov[pos].iov_len > Uint32(nBytesSent));
        iov[pos].iov_len -= nBytesSent;
        iov[pos].iov_base = ((char*)(iov[pos].iov_base))+nBytesSent;
      }
      continue;
    }
    else
    {
      int err = my_socket_errno();
      if (!(DISCONNECT_ERRNO(err, nBytesSent)))
      {
        if (sum_sent)
        {
          goto ok;
        }
        else
        {
          return remain;
        }
      }

#if defined DEBUG_TRANSPORTER
      g_eventLogger->error("Send Failure(disconnect==%d) to node = %d "
                           "nBytesSent = %d "
                           "errno = %d strerror = %s",
                           DISCONNECT_ERRNO(err, nBytesSent),
                           remoteNodeId, nBytesSent, my_socket_errno(),
                           (char*)ndbstrerror(err));
#endif
      do_disconnect(err);
      return 0;
    }
  }

ok:
  assert(sum >= sum_sent);
  iovec_data_sent(sum_sent);
  sendCount += send_cnt;
  sendSize  += sum_sent;
  if(sendCount >= reportFreq)
  {
    get_callback_obj()->reportSendLen(remoteNodeId, sendCount, sendSize);
    sendCount = 0;
    sendSize  = 0;
  }

  return sum - sum_sent; // 0 if every thing flushed else >0
}