"Fossies" - the Fresh Open Source Software Archive

Member "mariadb-connector-c-3.0.8-src/unittest/libmariadb/async.c" (18 Dec 2018, 6617 Bytes) of package /linux/misc/mariadb-connector-c-3.0.8-src.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "async.c": 3.0.3-src_vs_3.0.4-src.

    1 /*
    2   Copyright 2011 Kristian Nielsen and Monty Program Ab.
    3 
    4   This file is free software; you can redistribute it and/or
    5   modify it under the terms of the GNU Lesser General Public
    6   License as published by the Free Software Foundation; either
    7   version 2.1 of the License, or (at your option) any later version.
    8 
    9   This library is distributed in the hope that it will be useful,
   10   but WITHOUT ANY WARRANTY; without even the implied warranty of
   11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12   Lesser General Public License for more details.
   13 
   14   You should have received a copy of the GNU General Public License
   15   along with this.  If not, see <http://www.gnu.org/licenses/>.
   16 */
   17 #include "my_test.h"
   18 #include "ma_common.h"
   19 
   20 
   21 #ifndef _WIN32
   22 #include <poll.h>
   23 #else
   24 #include <winsock2.h>
   25 #endif
   26 
   27 #include <stdlib.h>
   28 #include <stdio.h>
   29 #include <mysql.h>
   30 
   31 my_bool skip_async= 0;
   32 
   33 static int test_async(MYSQL *mysql)
   34 {
   35   int type;
   36   mariadb_get_info(mysql, MARIADB_CONNECTION_PVIO_TYPE, &type);
   37   if (type > MARIADB_CONNECTION_TCP)
   38   {
   39     skip_async= 1;
   40     diag("Asnyc IO not supported");
   41   }
   42   return OK;
   43 }
   44 
   45 static int
   46 wait_for_mysql(MYSQL *mysql, int status)
   47 {
   48 #ifdef _WIN32
   49   fd_set rs, ws, es;
   50   int res;
   51   struct timeval tv, *timeout;
   52   my_socket s= mysql_get_socket(mysql);
   53   FD_ZERO(&rs);
   54   FD_ZERO(&ws);
   55   FD_ZERO(&es);
   56   if (status & MYSQL_WAIT_READ)
   57     FD_SET(s, &rs);
   58   if (status & MYSQL_WAIT_WRITE)
   59     FD_SET(s, &ws);
   60   if (status & MYSQL_WAIT_EXCEPT)
   61     FD_SET(s, &es);
   62   if (status & MYSQL_WAIT_TIMEOUT)
   63   {
   64     tv.tv_sec= mysql_get_timeout_value(mysql);
   65     tv.tv_usec= 0;
   66     timeout= &tv;
   67   }
   68   else
   69     timeout= NULL;
   70   res= select(1, &rs, &ws, &es, timeout);
   71   if (res == 0)
   72     return MYSQL_WAIT_TIMEOUT;
   73   else if (res == SOCKET_ERROR)
   74   {
   75     /*
   76       In a real event framework, we should handle errors and re-try the select.
   77     */
   78     return MYSQL_WAIT_TIMEOUT;
   79   }
   80   else
   81   {
   82     int status= 0;
   83     if (FD_ISSET(s, &rs))
   84       status|= MYSQL_WAIT_READ;
   85     if (FD_ISSET(s, &ws))
   86       status|= MYSQL_WAIT_WRITE;
   87     if (FD_ISSET(s, &es))
   88       status|= MYSQL_WAIT_EXCEPT;
   89     return status;
   90   }
   91 #else
   92   struct pollfd pfd;
   93   int timeout;
   94   int res= -1;
   95 
   96   pfd.fd= mysql_get_socket(mysql);
   97   pfd.events=
   98     (status & MYSQL_WAIT_READ ? POLLIN : 0) |
   99     (status & MYSQL_WAIT_WRITE ? POLLOUT : 0) |
  100     (status & MYSQL_WAIT_EXCEPT ? POLLPRI : 0);
  101   if (status & MYSQL_WAIT_TIMEOUT)
  102   {
  103     timeout= mysql_get_timeout_value_ms(mysql);
  104   }
  105   else
  106     timeout= -1;
  107   do {
  108     res= poll(&pfd, 1, timeout);
  109   } while (res == -1 && errno == EINTR);
  110   if (res == 0)
  111     return MYSQL_WAIT_TIMEOUT;
  112   else if (res < 0)
  113   {
  114     /*
  115       In a real event framework, we should handle EINTR and re-try the poll.
  116     */
  117     return MYSQL_WAIT_TIMEOUT;
  118   }
  119   else
  120   {
  121     int status= 0;
  122     if (pfd.revents & POLLIN)
  123       status|= MYSQL_WAIT_READ;
  124     if (pfd.revents & POLLOUT)
  125       status|= MYSQL_WAIT_WRITE;
  126     if (pfd.revents & POLLPRI)
  127       status|= MYSQL_WAIT_EXCEPT;
  128     return status;
  129   }
  130 #endif
  131 }
  132 
  133 static int async1(MYSQL *unused __attribute__((unused)))
  134 {
  135   int err= 0, rc;
  136   MYSQL mysql, *ret;
  137   MYSQL_RES *res;
  138   MYSQL_ROW row;
  139   int status;
  140   uint default_timeout;
  141   int i;
  142 
  143   if (skip_async)
  144     return SKIP;
  145 
  146   for (i=0; i < 100; i++)
  147   {
  148 
  149     mysql_init(&mysql);
  150     rc= mysql_options(&mysql, MYSQL_OPT_NONBLOCK, 0);
  151     check_mysql_rc(rc, (MYSQL *)&mysql);
  152 
  153     /* set timeouts to 300 microseconds */
  154     default_timeout= 3;
  155     mysql_options(&mysql, MYSQL_OPT_READ_TIMEOUT, &default_timeout);
  156     mysql_options(&mysql, MYSQL_OPT_CONNECT_TIMEOUT, &default_timeout);
  157     mysql_options(&mysql, MYSQL_OPT_WRITE_TIMEOUT, &default_timeout);
  158     mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, "myapp");
  159     if (force_tls)
  160       mysql_ssl_set(&mysql, NULL, NULL, NULL, NULL,NULL);
  161 
  162     /* Returns 0 when done, else flag for what to wait for when need to block. */
  163     status= mysql_real_connect_start(&ret, &mysql, hostname, username, password, schema, port, socketname, 0);
  164     while (status)
  165     {
  166       status= wait_for_mysql(&mysql, status);
  167       status= mysql_real_connect_cont(&ret, &mysql, status);
  168     }
  169     if (!ret)
  170     {
  171       diag("Error: %s", mysql_error(&mysql));
  172       FAIL_IF(!ret, "Failed to mysql_real_connect()");
  173     }
  174 
  175     if (force_tls && !mysql_get_ssl_cipher(&mysql))
  176     {
  177       diag("Error: No tls connection");
  178       return FAIL;
  179     }
  180 
  181     status= mysql_real_query_start(&err, &mysql, SL("SHOW STATUS"));
  182     while (status)
  183     {
  184       status= wait_for_mysql(&mysql, status);
  185       status= mysql_real_query_cont(&err, &mysql, status);
  186     }
  187     FAIL_IF(err, "mysql_real_query() returns error");
  188 
  189     /* This method cannot block. */
  190     res= mysql_use_result(&mysql);
  191     FAIL_IF(!res, "mysql_use_result() returns error");
  192 
  193     for (;;)
  194     {
  195       status= mysql_fetch_row_start(&row, res);
  196       while (status)
  197       {
  198         status= wait_for_mysql(&mysql, status);
  199         status= mysql_fetch_row_cont(&row, res, status);
  200       }
  201       if (!row)
  202         break;
  203     }
  204     FAIL_IF(mysql_errno(&mysql), "Got error while retrieving rows");
  205     mysql_free_result(res);
  206 
  207     /*
  208       mysql_close() sends a COM_QUIT packet, and so in principle could block
  209       waiting for the socket to accept the data.
  210       In practise, for many applications it will probably be fine to use the
  211       blocking mysql_close().
  212      */
  213     status= mysql_close_start(&mysql);
  214     while (status)
  215     {
  216       status= wait_for_mysql(&mysql, status);
  217       status= mysql_close_cont(&mysql, status);
  218     }
  219   }
  220   return OK;
  221 }
  222 
  223 static int test_conc131(MYSQL *unused __attribute__((unused)))
  224 {
  225   int rc;
  226   /* this test needs to run under valgrind */
  227   MYSQL *mysql;
  228   
  229   if (skip_async)
  230     return SKIP;
  231 
  232   mysql= mysql_init(NULL);
  233   rc= mysql_options(mysql, MYSQL_OPT_NONBLOCK, 0);
  234   check_mysql_rc(rc, mysql);
  235   mysql_close(mysql);
  236   return OK;
  237 }
  238 
  239 static int test_conc129(MYSQL *unused __attribute__((unused)))
  240 {
  241   MYSQL *mysql;
  242   
  243   if (skip_async)
  244     return SKIP;
  245 
  246   mysql= mysql_init(NULL);
  247   FAIL_IF(mysql_close_start(mysql), "No error expected");
  248   return OK;
  249 }
  250 
  251 
  252 struct my_tests_st my_tests[] = {
  253   {"test_async", test_async, TEST_CONNECTION_DEFAULT, 0,  NULL,  NULL},
  254   {"async1", async1, TEST_CONNECTION_DEFAULT, 0,  NULL,  NULL},
  255   {"test_conc131", test_conc131, TEST_CONNECTION_NONE, 0,  NULL,  NULL},
  256   {"test_conc129", test_conc129, TEST_CONNECTION_NONE, 0,  NULL,  NULL},
  257   {NULL, NULL, 0, 0, NULL, NULL}
  258 };
  259 
  260 
  261 int main(int argc, char **argv)
  262 {
  263   if (argc > 1)
  264     get_options(argc, argv);
  265 
  266   get_envvars();
  267 
  268   run_tests(my_tests);
  269 
  270   return(exit_status());
  271 }