"Fossies" - the Fresh Open Source Software Archive

Member "mariadb-connector-c-3.0.8-src/include/ma_context.h" (18 Dec 2018, 6678 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.

    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 
   18 /*
   19   Simple API for spawning a co-routine, to be used for async libmysqlclient.
   20 
   21   Idea is that by implementing this interface using whatever facilities are
   22   available for given platform, we can use the same code for the generic
   23   libmysqlclient-async code.
   24 
   25   (This particular implementation uses Posix ucontext swapcontext().)
   26 */
   27 
   28 #ifdef _WIN32
   29 #define MY_CONTEXT_USE_WIN32_FIBERS 1
   30 #elif defined(__GNUC__) && __GNUC__ >= 3 && defined(__x86_64__) && !defined(__ILP32__)
   31 #define MY_CONTEXT_USE_X86_64_GCC_ASM
   32 #elif defined(__GNUC__) && __GNUC__ >= 3 && defined(__i386__)
   33 #define MY_CONTEXT_USE_I386_GCC_ASM
   34 #elif defined(HAVE_UCONTEXT_H)
   35 #define MY_CONTEXT_USE_UCONTEXT
   36 #else
   37 #define MY_CONTEXT_DISABLE
   38 #endif
   39 
   40 #ifdef MY_CONTEXT_USE_WIN32_FIBERS
   41 struct my_context {
   42   void (*user_func)(void *);
   43   void *user_arg;
   44   void *app_fiber;
   45   void *lib_fiber;
   46   int return_value;
   47 #ifndef DBUG_OFF
   48   void *dbug_state;
   49 #endif
   50 };
   51 #endif
   52 
   53 
   54 #ifdef MY_CONTEXT_USE_UCONTEXT
   55 #include <ucontext.h>
   56 
   57 struct my_context {
   58   void (*user_func)(void *);
   59   void *user_data;
   60   void *stack;
   61   size_t stack_size;
   62   ucontext_t base_context;
   63   ucontext_t spawned_context;
   64   int active;
   65 #ifdef HAVE_VALGRIND
   66   unsigned int valgrind_stack_id;
   67 #endif
   68 #ifndef DBUG_OFF
   69   void *dbug_state;
   70 #endif
   71 };
   72 #endif
   73 
   74 
   75 #ifdef MY_CONTEXT_USE_X86_64_GCC_ASM
   76 #include <stdint.h>
   77 
   78 struct my_context {
   79   uint64_t save[9];
   80   void *stack_top;
   81   void *stack_bot;
   82 #ifdef HAVE_VALGRIND
   83   unsigned int valgrind_stack_id;
   84 #endif
   85 #ifndef DBUG_OFF
   86   void *dbug_state;
   87 #endif
   88 };
   89 #endif
   90 
   91 
   92 #ifdef MY_CONTEXT_USE_I386_GCC_ASM
   93 #include <stdint.h>
   94 
   95 struct my_context {
   96   uint64_t save[7];
   97   void *stack_top;
   98   void *stack_bot;
   99 #ifdef HAVE_VALGRIND
  100   unsigned int valgrind_stack_id;
  101 #endif
  102 #ifndef DBUG_OFF
  103   void *dbug_state;
  104 #endif
  105 };
  106 #endif
  107 
  108 
  109 #ifdef MY_CONTEXT_DISABLE
  110 struct my_context {
  111   int dummy;
  112 };
  113 #endif
  114 
  115 /*
  116   Initialize an asynchroneous context object.
  117   Returns 0 on success, non-zero on failure.
  118 */
  119 extern int my_context_init(struct my_context *c, size_t stack_size);
  120 
  121 /* Free an asynchroneous context object, deallocating any resources used. */
  122 extern void my_context_destroy(struct my_context *c);
  123 
  124 /*
  125   Spawn an asynchroneous context. The context will run the supplied user
  126   function, passing the supplied user data pointer.
  127 
  128   The context must have been initialised with my_context_init() prior to
  129   this call.
  130 
  131   The user function may call my_context_yield(), which will cause this
  132   function to return 1. Then later my_context_continue() may be called, which
  133   will resume the asynchroneous context by returning from the previous
  134   my_context_yield() call.
  135 
  136   When the user function returns, this function returns 0.
  137 
  138   In case of error, -1 is returned.
  139 */
  140 extern int my_context_spawn(struct my_context *c, void (*f)(void *), void *d);
  141 
  142 /*
  143   Suspend an asynchroneous context started with my_context_spawn.
  144 
  145   When my_context_yield() is called, execution immediately returns from the
  146   last my_context_spawn() or my_context_continue() call. Then when later
  147   my_context_continue() is called, execution resumes by returning from this
  148   my_context_yield() call.
  149 
  150   Returns 0 if ok, -1 in case of error.
  151 */
  152 extern int my_context_yield(struct my_context *c);
  153 
  154 /*
  155   Resume an asynchroneous context. The context was spawned by
  156   my_context_spawn(), and later suspended inside my_context_yield().
  157 
  158   The asynchroneous context may be repeatedly suspended with
  159   my_context_yield() and resumed with my_context_continue().
  160 
  161   Each time it is suspended, this function returns 1. When the originally
  162   spawned user function returns, this function returns 0.
  163 
  164   In case of error, -1 is returned.
  165 */
  166 extern int my_context_continue(struct my_context *c);
  167 
  168 struct st_ma_pvio;
  169 
  170 struct mysql_async_context {
  171   /*
  172     This is set to the value that should be returned from foo_start() or
  173     foo_cont() when a call is suspended.
  174   */
  175   unsigned int events_to_wait_for;
  176   /*
  177     It is also set to the event(s) that triggered when a suspended call is
  178     resumed, eg. whether we woke up due to connection completed or timeout
  179     in mysql_real_connect_cont().
  180   */
  181   unsigned int events_occured;
  182   /*
  183     This is set to the result of the whole asynchronous operation when it
  184     completes. It uses a union, as different calls have different return
  185     types.
  186   */
  187   union {
  188     void *r_ptr;
  189     const void *r_const_ptr;
  190     int r_int;
  191     my_bool r_my_bool;
  192   } ret_result;
  193   /*
  194     The timeout value (in millisecods), for suspended calls that need to wake
  195     up on a timeout (eg. mysql_real_connect_start().
  196   */
  197   unsigned int timeout_value;
  198   /*
  199     This flag is set when we are executing inside some asynchronous call
  200     foo_start() or foo_cont(). It is used to decide whether to use the
  201     synchronous or asynchronous version of calls that may block such as
  202     recv().
  203 
  204     Note that this flag is not set when a call is suspended, eg. after
  205     returning from foo_start() and before re-entering foo_cont().
  206   */
  207   my_bool active;
  208   /*
  209     This flag is set when an asynchronous operation is in progress, but
  210     suspended. Ie. it is set when foo_start() or foo_cont() returns because
  211     the operation needs to block, suspending the operation.
  212 
  213     It is used to give an error (rather than crash) if the application
  214     attempts to call some foo_cont() method when no suspended operation foo is
  215     in progress.
  216   */
  217   my_bool suspended;
  218   /*
  219     If non-NULL, this is a pointer to a callback hook that will be invoked with
  220     the user data argument just before the context is suspended, and just after
  221     it is resumed.
  222   */
  223   struct st_ma_pvio *pvio;
  224   void (*suspend_resume_hook)(my_bool suspend, void *user_data);
  225   void *suspend_resume_hook_user_data;
  226   /*
  227     This is used to save the execution contexts so that we can suspend an
  228     operation and switch back to the application context, to resume the
  229     suspended context later when the application re-invokes us with
  230     foo_cont().
  231   */
  232   struct my_context async_context;
  233 };