/* {{{ size_t ma_pvio_write */
ssize_t ma_pvio_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length)
{
  ssize_t r= 0;

  if (!pvio)
   return -1;

  /* secure connection */
#ifdef HAVE_TLS
  if (pvio->ctls)
  {
    r= ma_pvio_tls_write(pvio->ctls, buffer, length);
    goto end;
  }
  else
#endif
  if (IS_PVIO_ASYNC_ACTIVE(pvio))
  {
    r= ma_pvio_write_async(pvio, buffer, length);
    goto end;
  }
  else
  {
    if (IS_PVIO_ASYNC(pvio))
    {
      /*
        If switching from non-blocking to blocking API usage, set the socket
        back to blocking mode.
      */
      my_bool old_mode;
      ma_pvio_blocking(pvio, TRUE, &old_mode);
    }
  }

  if (pvio->methods->write)
    r= pvio->methods->write(pvio, buffer, length);
end:
  if (pvio_callback)
  {
    void (*callback)(int mode, MYSQL *mysql, const uchar *buffer, size_t length);
    LIST *p= pvio_callback;
    while (p)
    {
      callback= p->data;
      callback(1, pvio->mysql, buffer, r);
      p= p->next;
    }
  }
  return r;
}
Beispiel #2
0
/* {{{ size_t ma_pvio_write */
size_t ma_pvio_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length)
{
  size_t r;

  if (!pvio)
   return -1;

  /* secure connection */
#ifdef HAVE_SSL
  if (pvio->ctls)
  {
    r= ma_pvio_tls_write(pvio->ctls, buffer, length);
    goto end;
  }
  else
#endif
#ifdef HAVE_NONBLOCK
  if (IS_PVIO_ASYNC_ACTIVE(pvio))
  {
    r= ma_pvio_write_async(pvio, buffer, length);
    goto end;
  }
  else
#endif
  {
    if (IS_PVIO_ASYNC(pvio))
    {
      /*
        If switching from non-blocking to blocking API usage, set the socket
        back to blocking mode.
      */
      my_bool old_mode;
      ma_pvio_blocking(pvio, TRUE, &old_mode);
    }
  }

  if (pvio->methods->write)
    r= pvio->methods->write(pvio, buffer, length);
end:  
  if (pvio->callback)
    pvio->callback(pvio, 0, buffer, r);
  return r;
}
/* Asynchronous connect(); socket must already be set non-blocking. */
int
my_connect_async(MARIADB_PVIO *pvio,
                 const struct sockaddr *name, uint namelen, int vio_timeout)
{
  int res;
  size_socket s_err_size;
  struct mysql_async_context *b= pvio->mysql->options.extension->async_context;
  my_socket sock;

  ma_pvio_get_handle(pvio, &sock);

  /* Make the socket non-blocking. */
  ma_pvio_blocking(pvio, 0, 0);

  b->events_to_wait_for= 0;
  /*
    Start to connect asynchronously.
    If this will block, we suspend the call and return control to the
    application context. The application will then resume us when the socket
    polls ready for write, indicating that the connection attempt completed.
  */
  res= connect(sock, name, namelen);
  if (res != 0)
  {
#ifdef _WIN32
    int wsa_err= WSAGetLastError();
    if (wsa_err != WSAEWOULDBLOCK)
      return res;
    b->events_to_wait_for|= MYSQL_WAIT_EXCEPT;
#else
    int err= errno;
    if (err != EINPROGRESS && err != EALREADY && err != EAGAIN)
      return res;
#endif
    b->events_to_wait_for|= MYSQL_WAIT_WRITE;
    if (vio_timeout >= 0)
    {
      b->timeout_value= vio_timeout;
      b->events_to_wait_for|= MYSQL_WAIT_TIMEOUT;
    }
    else
      b->timeout_value= 0;
    if (b->suspend_resume_hook)
      (*b->suspend_resume_hook)(TRUE, b->suspend_resume_hook_user_data);
    my_context_yield(&b->async_context);
    if (b->suspend_resume_hook)
      (*b->suspend_resume_hook)(FALSE, b->suspend_resume_hook_user_data);
    if (b->events_occured & MYSQL_WAIT_TIMEOUT)
      return -1;

    s_err_size= sizeof(res);
    if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char*) &res, &s_err_size) != 0)
      return -1;
    if (res)
    {
      errno= res;
      return -1;
    }
  }
  return res;
}