{{ header_comment }}

/*
 * Define two sets of functions: background functions and future functions.

 * A background function like background_mongoc_cursor_next runs a driver
 * operation on a thread.

 * A future function like future_mongoc_cursor_next launches the background
 * operation and returns a future_t that will resolve when the operation
 * finishes.
 *
 * These are used with mock_server_t so you can run the driver on a thread while
 * controlling the server from the main thread.
 */

#include <mongoc/mongoc-topology-private.h>

#include "mock_server/future-functions.h"

{% for F in future_functions %}
static
BSON_THREAD_FUN (background_{{ F.name }}, data)
{
   future_t *future = (future_t *) data;
   future_value_t return_value;

   return_value.type = future_value_{{ F.ret_type }}_type;
{% if F.ret_type == 'void' %}
   {{ F.name }} ({% for P in F.params %}
      future_value_get_{{ P.type_name }} (future_get_param (future, {{ loop.index0 }})){% if not loop.last %},{% endif %}{% endfor %});
{% else %}
   future_value_set_{{ F.ret_type }} (
      &return_value,
      {{ F.name }} ({% for P in F.params %}
         future_value_get_{{ P.type_name }} (future_get_param (future, {{ loop.index0 }})){% if not loop.last %},{% endif %}{% endfor %}
      ));
{% endif %}
   future_resolve (future, return_value);

   BSON_THREAD_RETURN;
}
{% endfor %}
{% for F in future_functions %}

future_t *
{{ F|future_function_name }} ({% for P in F.params %}
   {{ P.type_name }} {{ P.name }}{% if not loop.last %},{% endif %}{% endfor %})
{
   future_t *future = future_new (future_value_{{ F.ret_type }}_type,
                                  {{ F.params | length }});
   {% for P in F.params %}
   future_value_set_{{ P.type_name }} (
      future_get_param (future, {{ loop.index0 }}), {{ P.name }});
   {% endfor %}
   future_start (future, background_{{ F.name }});
   return future;
}
{%- endfor %}
