示例#1
0
static int BSslHandleAsync(SslBindCtx *pCtx, int iCode, int iDefError, int iTimeo)
{
	int iError, iResult = 0;
	SYS_fd_set FdSet;

	if ((iError = SSL_get_error(pCtx->pSSL, iCode)) != SSL_ERROR_NONE) {
		SYS_FD_ZERO(&FdSet);
		SYS_FD_SET(pCtx->SockFD, &FdSet);
		if (iError == SSL_ERROR_WANT_READ) {
			if (SysSelect((long) pCtx->SockFD + 1, &FdSet, NULL,
				      NULL, iTimeo) < 0)
				return ErrGetErrorCode();
			iResult = 1;
		} else if (iError == SSL_ERROR_WANT_WRITE) {
			if (SysSelect((long) pCtx->SockFD + 1, NULL, &FdSet,
				      NULL, iTimeo) < 0)
				return ErrGetErrorCode();
			iResult = 1;
		} else {
			ErrSetErrorCode(iDefError);
			iResult = iDefError;
		}
	}

	return iResult;
}
示例#2
0
enum MqErrorE
pIoSelect (
  struct MqIoS * const io,
  enum MqIoSelectE const typ,
  struct timeval * const timeout
)
{
  // set in GenericCreateSocket or in PipeCreate -> SysConnect need this
  register MQ_SOCK const sock = *io->sockP;
  fd_set *fds, *readfds = NULL, *writefds = NULL;

  if (sock < 0)
    return MQ_CONTINUE;	    // nothing found

  fds = &io->fdset;

  // build fds
  FD_SET (sock, fds);

  // compose
  switch (typ) {
    case MQ_SELECT_RECV:
      readfds = fds;
      break;
    case MQ_SELECT_SEND:
      writefds = fds;
      break;
  }

  // do the select
  MqErrorReturn (SysSelect (io->context, (sock+1), readfds, writefds, timeout));
}
示例#3
0
enum MqErrorE
SysSend (
  struct MqS * const context,
  MQ_SOCK hdl,
  MQ_BIN buf,
  MQ_SIZE numBytes,
  int flags,
  MQ_TIME_T timeout
)
{
  MQ_SIZE ldata = 0;
  MQ_INT trycount = (MQ_INT) (timeout*100);

  // send data from buf
  do {
    ldata = send (hdl, (const MQ_buf_T) buf, numBytes, flags);
//printLV("numBytes<%d>, hdl<%d>, ldata<%d>\n", numBytes, hdl, ldata);
    // check for errors
    if (unlikely (ldata == -1)) {
//printLV("ERROR sock<%i>, numBytes<%i>, errnum<%i>, str<%s>\n", hdl, numBytes, sSysGetErrorNum, strerror(errno));
      switch (sSysGetErrorNum) {
        case WIN32_WSA (EWOULDBLOCK): {
	  // waiting for "send" is buggy -> just use 0.01 sec and try send again on "timeout" (MQ_CONTINUE)
	  struct timeval tv = {(long) 0L, 10000L};
	  fd_set fds;
          if (trycount <= 0) return MqErrorDbV (MQ_ERROR_TIMEOUT, timeout);
	  // now wait until the socket become send-able
	  FD_ZERO(&fds);
	  FD_SET(hdl, &fds);
	  switch (SysSelect (context, (hdl+1), NULL, &fds, &tv)) {
	    case MQ_OK:
	      break;
	    case MQ_CONTINUE:
	      trycount -= 1;
	      continue; // with "do" loop
	    case MQ_ERROR:
	      pIoCloseSocket (__func__, context->link.io);
	      return MqErrorStack (context);
	  }
	  ldata = 0;
	  break;
	}
	case WIN32_WSA (ECONNRESET):
	case WIN32_WSA (EBADF): {
          pIoCloseSocket (__func__, context->link.io);
	  return pErrorSetExitWithCheck (context);
	}
        default:
          pIoCloseSocket (__func__, context->link.io);
          return sSysMqErrorMsg (context, __func__, "send");
      }
    }
    buf += ldata;
    numBytes -= ldata;
  }
  while (numBytes > 0);
  return MQ_OK;
}
示例#4
0
enum MqErrorE
SysRecv (
  struct MqS * const context,
  MQ_SOCK const hdl,
  MQ_BIN buf,
  MQ_SIZE numBytes,
  MQ_SIZE * const newSize,
  MQ_TIME_T timeout
)
{
  int const flags = 0;
  register MQ_SIZE ldata = 0;
  *newSize = 0;

  // recv data in buf
  do {
    ldata = recv (hdl, (MQ_buf_T) buf, numBytes, flags);

    // check for errors
    if (unlikely (ldata <= 0)) {
	if (ldata == -1) {
//MqDLogV(context,0,"ERROR sock<%i>, numBytes<%i>, str<%s>\n", hdl, numBytes, strerror(errno));
	  switch (sSysGetErrorNum) {
	    case WIN32_WSA (EWOULDBLOCK): {
	      struct timeval tv = {(long)timeout, 0L};
	      fd_set fds;
	      FD_ZERO(&fds);
	      FD_SET(hdl, &fds);
	      // now wait until the socket become recv-able
	      switch (SysSelect (context, (hdl+1), &fds, NULL, &tv)) {
		case MQ_OK:
		  break;
		case MQ_CONTINUE:
		  return MqErrorDbV (MQ_ERROR_TIMEOUT, timeout);
		case MQ_ERROR:
		  pIoCloseSocket (__func__, context->link.io);
		  return MqErrorStack(context);
	      }
	      ldata = 0;
	      break;
	    }
	    case WIN32_WSA (ECONNRESET):
	    case WIN32_WSA (EBADF): {
	      pIoCloseSocket (__func__, context->link.io);
	      return pErrorSetExitWithCheck (context);
	    }
	    default:
	      pIoCloseSocket (__func__, context->link.io);
	      return sSysMqErrorMsg (context, __func__, "recv");
	  }
	} else if (ldata == 0) {
	  pIoCloseSocket (__func__, context->link.io);
	  return pErrorSetExitWithCheck (context);
	}
    }

    buf += ldata;
    numBytes -= ldata;
    *newSize += ldata;
  }
  while (numBytes > 0);

  return MQ_OK;
}
示例#5
0
enum MqErrorE
SysSelect (
  struct MqS * const context,
  int n,
  fd_set * readfds,
  fd_set * writefds,
  struct timeval const * const timeout
)
{
  int ret;
  struct timeval tv = *timeout;
  sSysSetErrorNum(0);
  ret = MqSysSelect (n, (void*)readfds, (void*)writefds, NULL, &tv);
  switch (ret) {
    case 0:
      return MQ_CONTINUE;   // timeout
    case SOCKET_ERROR:
      switch (sSysGetErrorNum) {
        /*
#ifdef MQ_IS_WIN32
	case WIN32_WSA (ENOTSOCK):
          M0
          MqSysSleep(context,1);
          return MQ_CONTINUE;
        case WIN32_WSA (EFAULT):
          M1
          MqSysSleep(context,1);
          return MQ_CONTINUE;
#endif
          */
	case WIN32_WSA (EINTR):
          return MQ_CONTINUE;
	//case WIN32_WSA (ENOTSOCK):
        //case WIN32_WSA (EFAULT):
	case WIN32_WSA (EBADF): {
	  // check all sockets's to get the bad one
	  MQ_SOCK i;
	  int num=0;
	  fd_set fd_test, *fds = NULL, *read_test = NULL, *write_test = NULL;
	  struct timeval timeout = {0L,0L};
	  struct MqS const * sockmq = NULL;
	  MQ_SOCK sock=-1;
	  // read or write ?
	  if (readfds != NULL) {
	    read_test = &fd_test;
	    fds = readfds;
	  } else {
	    write_test = &fd_test;
	    fds = writefds;
	  }
	  // get the number of sockets
	  for (i=0;i<n;i++) {
	    if (FD_ISSET(i,fds)) {
	      num++;
	      sock = i;
              //printI(sock)
	    }
	  }
          // only one socket?
	  if (num == 1) {
            sockmq = pIoGetMsgqueFromSocket(context->link.io,sock);
	    if (sockmq == NULL) {
	      return sSysMqErrorMsg (context, __func__, "select");
	    } else if (sockmq == context) {
	      pIoCloseSocket (__func__, context->link.io);
	      return pErrorSetExitWithCheck (context);
	    } else {
	      pIoCloseSocket (__func__, sockmq->link.io);
	      return MQ_CONTINUE;
	    }
	  }
	  // ok, more than one socket check every socket
	  for (i=0;i<n;i++) {
	    if (!FD_ISSET(i,fds)) continue;
	    FD_ZERO (&fd_test);
	    FD_SET (i, &fd_test);
	    if (MqErrorCheckI (SysSelect(context,i+1,read_test,write_test,&timeout))) {
	      return MQ_ERROR;
	    }
	  }
	  return MQ_CONTINUE;
	}
	default:
          return sSysMqErrorMsg (context, __func__, "select");
      }
  }
  return MQ_OK;
}