コード例 #1
0
ファイル: send.c プロジェクト: BackupTheBerlios/shadowircd
/*
 ** send_queued_write
 **      This is called when there is a chance that some output would
 **      be possible. This attempts to empty the send queue as far as
 **      possible, and then if any data is left, a write is rescheduled.
 */
void
send_queued_write(struct Client *to)
{
  int retlen;
#ifndef NDEBUG
  struct hook_io_data hdata;
#endif
  struct dbuf_block *first;
  
  /*
   ** Once socket is marked dead, we cannot start writing to it,
   ** even if the error is removed...
   */
  if (IsDead(to) || IsSendqBlocked(to))
    return;  /* no use calling send() now */

  /* Next, lets try to write some data */
  if (dbuf_length(&to->localClient->buf_sendq))
  {
#ifndef NDEBUG
    hdata.connection = to;
#endif
    do {
      first = to->localClient->buf_sendq.blocks.head->data;
#ifdef HAVE_LIBCRYPTO
      if(IsSSL(to))
      {
        retlen = safe_SSL_write(to, first->data, first->size);
        printf("safe_ssl_write: writing: %s\n", first->data);
        printf("safe_ssl_write: %d written\n", retlen);
        if (retlen <= 0)
         break;
      }
      else
#endif
      if ((retlen = send(to->localClient->fd, first->data,
                         first->size, 0)) <= 0)
        break;

#ifndef NDEBUG
      hdata.data = ((struct dbuf_block *)
                    to->localClient->buf_sendq.blocks.head->data)->data;
      hdata.len = retlen;
      hook_call_event("iosend", &hdata);
#endif
      dbuf_delete(&to->localClient->buf_sendq, retlen);

      /* We have some data written .. update counters */
      to->localClient->sendB += retlen;
      me.localClient->sendB += retlen;
      if (to->localClient->sendB > 1023)
      { 
        to->localClient->sendK += (to->localClient->sendB >> 10);
        to->localClient->sendB &= 0x03ff;        /* 2^10 = 1024, 3ff = 1023 */
      }
      else if (me.localClient->sendB > 1023)
      { 
        me.localClient->sendK += (me.localClient->sendB >> 10);
        me.localClient->sendB &= 0x03ff;
      }
コード例 #2
0
ファイル: bsd.c プロジェクト: J-Soft/UltimateIRCd
/*
 * deliver_it 
 *
 * Attempt to send a sequence of bytes to the connection. 
 * Returns 
 *  < 0     Some fatal error occurred, (but not EWOULDBLOCK). 
 *    his return is a request to close the socket and clean up the link.
 *  >= 0    No real error occurred, returns the number of bytes actually
 *    transferred. EWOULDBLOCK and other similar conditions should be mapped
 *    to zero return.
 *    Upper level routine will have to decide what to do with
 *    those unwritten bytes... 
 * *NOTE*  alarm calls have been preserved, so this should work equally 
 *  well whether blocking or non-blocking mode is used...
 */
int
deliver_it (aClient * client_p, char *str, int len)
{
  int retval;
  aClient *acpt = client_p->acpt;
#ifdef	DEBUGMODE
  writecalls++;
#endif
#ifdef USE_SSL
  if (IsSSL (client_p) && client_p->ssl)
    retval = safe_SSL_write (client_p, str, len);
  else
#endif
    retval = send (client_p->fd, str, len, 0);

  /*
   * Convert WOULDBLOCK to a return of "0 bytes moved". This 
   * should occur only if socket was non-blocking. Note, that all is
   * Ok, if the 'write' just returns '0' instead of an error and
   * errno=EWOULDBLOCK. 
   */
  if (retval < 0 &&
#ifdef _WIN32
      (WSAGetLastError () == WSAEWOULDBLOCK ||
       WSAGetLastError () == WSAENOBUFS)
#else
      (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS)
#endif
    )
  {
    retval = 0;
    client_p->flags |= FLAGS_BLOCKED;
    set_fd_flags (client_p->fd, FDF_WANTWRITE);
    return (retval);            /* Just get out now... */
  }
  else if (retval > 0)
  {
    if (client_p->flags & FLAGS_BLOCKED)
    {
      client_p->flags &= ~FLAGS_BLOCKED;
      unset_fd_flags (client_p->fd, FDF_WANTWRITE);
    }
  }

#ifdef DEBUGMODE
  if (retval < 0)
  {
    writeb[0]++;
    Debug ((DEBUG_ERROR, "write error (%s) to %s",
            strerror (errno), client_p->name));
  }
  else if (retval == 0)
    writeb[1]++;
  else if (retval < 16)
    writeb[2]++;
  else if (retval < 32)
    writeb[3]++;
  else if (retval < 64)
    writeb[4]++;
  else if (retval < 128)
    writeb[5]++;
  else if (retval < 256)
    writeb[6]++;
  else if (retval < 512)
    writeb[7]++;
  else if (retval < 1024)
    writeb[8]++;
  else
    writeb[9]++;
#endif
  if (retval > 0)
  {
    client_p->sendB += retval;
    me.sendB += retval;
    if (client_p->sendB > 1023)
    {
      client_p->sendK += (client_p->sendB >> 10);
      client_p->sendB &= 0x03ff;        /* 2^10 = 1024, 3ff = 1023 */
    }