<HTML><BODY><div class="js-helper js-readmsg-msg"><div><div id="style_15699232780668908542_BODY"><div class="class_1569952764"><p>Hi!<br><br>Thanks for your review.<br></p><p>No, trigger_run didn't throw before refactoring. Triggers did throw,<br>but trigger_run wraps them in try..catch block. Only in the last<br>patch of this patchset try..catch block in trigger_run is removed<br>as far as triggers don't throw anymore.</p><p>Therefore applier_txn_rollback_cb was already ignoring that something<br>might go wrong inside trigger_run and I think it is fine as far as<br>this trigger_run processes replicaset.applier.on_rollback triggers<br>for the case where replication request failed to apply.<br><br><span data-mce-style="color: #222222;font-family: Rubik, Arial, sans-serif;font-size: 17px;" style="color: #222222;font-family: Rubik, Arial, sans-serif;font-size: 17px;">Sincerely,<br></span>Ilya Kosarev</p><blockquote style="border-left:1px solid #0857A6;margin:10px;padding:0 0 0 10px;">
        Понедельник, 30 сентября 2019, 22:14 +03:00 от Sergey Ostanevich <<a href="mailto:sergos@tarantool.org">sergos@tarantool.org</a>>:<br>
        <br>
        <div id="">






<div class="js-helper_mailru_css_attribute_postfix js-readmsg-msg_mailru_css_attribute_postfix">
        <style></style>
        <div>
                
                
            <div id="style_15698708771664628683_BODY_mailru_css_attribute_postfix">Hi Ilya!<br>
<br>
In the applier_txn_rollback_cb() I can see that <br>
trigger_run(&replicaset.applier.on_rollback, event) may return -1 in case <br>
of error, but it is ignored. Is it expected?<br>
I belive trigger_run() throwed an ecxeption before the refactoring, that<br>
had different meaning in this context?<br>
<br>
regards,<br>
Sergos<br>
<br>
<br>
On 23 Sep 18:56, Ilya Kosarev wrote:<br>
> Trigger function returning type is changed from void to int and<br>
> any non-zero value means the trigger was processed with an error.<br>
> A trigger can still raise an error - there is no more refactoring<br>
> except obvious `diag_raise();' --> `return -1;' replacement.<br>
> <br>
> Prerequisites: #4247<br>
> ---<br>
>  src/box/alter.cc            | 182 ++++++++++++++++++++++++------------<br>
>  src/box/applier.cc          |  17 ++--<br>
>  src/box/ck_constraint.c     |   9 +-<br>
>  src/box/ck_constraint.h     |   4 +-<br>
>  src/box/iproto.cc           |   3 +-<br>
>  src/box/lua/call.c          |   5 +-<br>
>  src/box/lua/sequence.c      |   3 +-<br>
>  src/box/lua/space.cc        |   3 +-<br>
>  src/box/memtx_space.c       |  17 ++--<br>
>  src/box/relay.cc            |   5 +-<br>
>  src/box/replication.cc      |  10 +-<br>
>  src/box/session.cc          |   3 +-<br>
>  src/box/txn.c               |  10 +-<br>
>  src/box/vinyl.c             |  44 +++++----<br>
>  src/box/vy_scheduler.c      |   3 +-<br>
>  src/lib/core/fiber.c        |   3 +-<br>
>  src/lib/core/trigger.cc     |   6 +-<br>
>  src/lib/core/trigger.h      |   2 +-<br>
>  src/lua/trigger.c           |   7 +-<br>
>  src/main.cc                 |   3 +-<br>
>  test/unit/cbus.c            |   3 +-<br>
>  test/unit/swim.c            |   6 +-<br>
>  test/unit/swim_test_utils.c |   3 +-<br>
>  23 files changed, 221 insertions(+), 130 deletions(-)<br>
> <br>
> diff --git a/src/box/alter.cc b/src/box/alter.cc<br>
> index bb3686d6e..e21dce5bf 100644<br>
> --- a/src/box/alter.cc<br>
> +++ b/src/box/alter.cc<br>
> @@ -859,7 +859,7 @@ struct mh_i32_t *AlterSpaceLock::registry;<br>
>   * of the dropped indexes.<br>
>   * Replace the old space with a new one in the space cache.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  alter_space_commit(struct trigger *trigger, void *event)<br>
>  {<br>
>    struct txn *txn = (struct txn *) event;<br>
> @@ -889,6 +889,7 @@ alter_space_commit(struct trigger *trigger, void *event)<br>
>    space_delete(alter->old_space);<br>
>    alter->old_space = NULL;<br>
>    alter_space_delete(alter);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -899,7 +900,7 @@ alter_space_commit(struct trigger *trigger, void *event)<br>
>   * Keep in mind that we may end up here in case of<br>
>   * alter_space_commit() failure (unlikely)<br>
>   */<br>
> -static void<br>
> +static int<br>
>  alter_space_rollback(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    struct alter_space *alter = (struct alter_space *) trigger->data;<br>
> @@ -918,6 +919,7 @@ alter_space_rollback(struct trigger *trigger, void * /* event */)<br>
>    space_swap_fk_constraints(alter->new_space, alter->old_space);<br>
>    space_cache_replace(alter->new_space, alter->old_space);<br>
>    alter_space_delete(alter);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -1645,12 +1647,13 @@ MoveCkConstraints::rollback(struct alter_space *alter)<br>
>  /**<br>
>   * Delete the space. It is already removed from the space cache.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_drop_space_commit(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) event;<br>
>    struct space *space = (struct space *)trigger->data;<br>
>    space_delete(space);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -1658,12 +1661,13 @@ on_drop_space_commit(struct trigger *trigger, void *event)<br>
>   * of all other events happened after the space was removed were<br>
>   * reverted by the cascading rollback.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_drop_space_rollback(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) event;<br>
>    struct space *space = (struct space *)trigger->data;<br>
>    space_cache_replace(NULL, space);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -1673,13 +1677,14 @@ on_drop_space_rollback(struct trigger *trigger, void *event)<br>
>   * By the time the space is removed, it should be empty: we<br>
>   * rely on cascading rollback.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_create_space_rollback(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) event;<br>
>    struct space *space = (struct space *)trigger->data;<br>
>    space_cache_replace(space, NULL);<br>
>    space_delete(space);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -1791,12 +1796,13 @@ update_view_references(struct Select *select, int update_value,<br>
>   * Trigger which is fired to commit creation of new SQL view.<br>
>   * Its purpose is to release memory of SELECT.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_create_view_commit(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) event;<br>
>    struct Select *select = (struct Select *)trigger->data;<br>
>    sql_select_delete(sql_get(), select);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -1804,13 +1810,14 @@ on_create_view_commit(struct trigger *trigger, void *event)<br>
>   * Decrements view reference counters of dependent spaces and<br>
>   * releases memory for SELECT.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_create_view_rollback(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) event;<br>
>    struct Select *select = (struct Select *)trigger->data;<br>
>    update_view_references(select, -1, true, NULL);<br>
>    sql_select_delete(sql_get(), select);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -1818,12 +1825,13 @@ on_create_view_rollback(struct trigger *trigger, void *event)<br>
>   * Its purpose is to decrement view reference counters of<br>
>   * dependent spaces and release memory for SELECT.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_drop_view_commit(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) event;<br>
>    struct Select *select = (struct Select *)trigger->data;<br>
>    sql_select_delete(sql_get(), select);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -1831,13 +1839,14 @@ on_drop_view_commit(struct trigger *trigger, void *event)<br>
>   * Release memory for struct SELECT compiled in<br>
>   * on_replace_dd_space trigger.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_drop_view_rollback(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) event;<br>
>    struct Select *select = (struct Select *)trigger->data;<br>
>    update_view_references(select, 1, true, NULL);<br>
>    sql_select_delete(sql_get(), select);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -1890,7 +1899,7 @@ on_drop_view_rollback(struct trigger *trigger, void *event)<br>
>   * dynamic space configuration such a check would be particularly<br>
>   * clumsy, so it is simply not done.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_replace_dd_space(struct trigger * /* trigger */, void *event)<br>
>  {<br>
>    struct txn *txn = (struct txn *) event;<br>
> @@ -2126,6 +2135,7 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)<br>
>            alter_space_do(stmt, alter);<br>
>            alter_guard.is_active = false;<br>
>    }<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -2186,7 +2196,7 @@ index_is_used_by_fk_constraint(struct rlist *fk_list, uint32_t iid)<br>
>   *   for offsets is relinquished to the slab allocator as tuples<br>
>   *   are modified.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_replace_dd_index(struct trigger * /* trigger */, void *event)<br>
>  {<br>
>    struct txn *txn = (struct txn *) event;<br>
> @@ -2363,6 +2373,7 @@ on_replace_dd_index(struct trigger * /* trigger */, void *event)<br>
>    (void) new UpdateSchemaVersion(alter);<br>
>    alter_space_do(stmt, alter);<br>
>    scoped_guard.is_active = false;<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -2376,7 +2387,7 @@ on_replace_dd_index(struct trigger * /* trigger */, void *event)<br>
>   * This is OK, because a WAL write error implies cascading<br>
>   * rollback of all transactions following this one.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_replace_dd_truncate(struct trigger * /* trigger */, void *event)<br>
>  {<br>
>    struct txn *txn = (struct txn *) event;<br>
> @@ -2385,7 +2396,7 @@ on_replace_dd_truncate(struct trigger * /* trigger */, void *event)<br>
>  <br>
>    if (new_tuple == NULL) {<br>
>            /* Space drop - nothing to do. */<br>
> -          return;<br>
> +          return 0;<br>
>    }<br>
>  <br>
>    uint32_t space_id =<br>
> @@ -2397,7 +2408,7 @@ on_replace_dd_truncate(struct trigger * /* trigger */, void *event)<br>
>             * Space creation during initial recovery -<br>
>             * nothing to do.<br>
>             */<br>
> -          return;<br>
> +          return 0;<br>
>    }<br>
>  <br>
>    /*<br>
> @@ -2439,6 +2450,7 @@ on_replace_dd_truncate(struct trigger * /* trigger */, void *event)<br>
>    (void) new MoveCkConstraints(alter);<br>
>    alter_space_do(stmt, alter);<br>
>    scoped_guard.is_active = false;<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /* {{{ access control */<br>
> @@ -2583,15 +2595,16 @@ user_def_new_from_tuple(struct tuple *tuple)<br>
>    return user;<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  user_cache_remove_user(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    struct tuple *tuple = (struct tuple *)trigger->data;<br>
>    uint32_t uid = tuple_field_u32_xc(tuple, BOX_USER_FIELD_ID);<br>
>    user_cache_delete(uid);<br>
> +  return 0;<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  user_cache_alter_user(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    struct tuple *tuple = (struct tuple *)trigger->data;<br>
> @@ -2600,12 +2613,13 @@ user_cache_alter_user(struct trigger *trigger, void * /* event */)<br>
>    /* Can throw if, e.g. too many users. */<br>
>    user_cache_replace(user);<br>
>    def_guard.is_active = false;<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
>   * A trigger invoked on replace in the user table.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_replace_dd_user(struct trigger * /* trigger */, void *event)<br>
>  {<br>
>    struct txn *txn = (struct txn *) event;<br>
> @@ -2665,6 +2679,7 @@ on_replace_dd_user(struct trigger * /* trigger */, void *event)<br>
>                    txn_alter_trigger_new(user_cache_alter_user, old_tuple);<br>
>            txn_stmt_on_rollback(stmt, on_rollback);<br>
>    }<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -2859,7 +2874,7 @@ func_def_new_from_tuple(struct tuple *tuple)<br>
>    return def;<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  on_create_func_rollback(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    /* Remove the new function from the cache and delete it. */<br>
> @@ -2867,30 +2882,33 @@ on_create_func_rollback(struct trigger *trigger, void * /* event */)<br>
>    func_cache_delete(func->def->fid);<br>
>    trigger_run_xc(&on_alter_func, func);<br>
>    func_delete(func);<br>
> +  return 0;<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  on_drop_func_commit(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    /* Delete the old function. */<br>
>    struct func *func = (struct func *)trigger->data;<br>
>    func_delete(func);<br>
> +  return 0;<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  on_drop_func_rollback(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    /* Insert the old function back into the cache. */<br>
>    struct func *func = (struct func *)trigger->data;<br>
>    func_cache_insert(func);<br>
>    trigger_run_xc(&on_alter_func, func);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
>   * A trigger invoked on replace in a space containing<br>
>   * functions on which there were defined any grants.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_replace_dd_func(struct trigger * /* trigger */, void *event)<br>
>  {<br>
>    struct txn *txn = (struct txn *) event;<br>
> @@ -2969,6 +2987,7 @@ on_replace_dd_func(struct trigger * /* trigger */, void *event)<br>
>                              "alter");<br>
>            }<br>
>    }<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /** Create a collation identifier definition from tuple. */<br>
> @@ -3057,27 +3076,29 @@ coll_id_def_new_from_tuple(struct tuple *tuple, struct coll_id_def *def)<br>
>  }<br>
>  <br>
>  /** Delete the new collation identifier. */<br>
> -static void<br>
> +static int<br>
>  on_create_collation_rollback(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) event;<br>
>    struct coll_id *coll_id = (struct coll_id *) trigger->data;<br>
>    coll_id_cache_delete(coll_id);<br>
>    coll_id_delete(coll_id);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  <br>
>  /** Free a deleted collation identifier on commit. */<br>
> -static void<br>
> +static int<br>
>  on_drop_collation_commit(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) event;<br>
>    struct coll_id *coll_id = (struct coll_id *) trigger->data;<br>
>    coll_id_delete(coll_id);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /** Put the collation identifier back on rollback. */<br>
> -static void<br>
> +static int<br>
>  on_drop_collation_rollback(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) event;<br>
> @@ -3086,13 +3107,14 @@ on_drop_collation_rollback(struct trigger *trigger, void *event)<br>
>    if (coll_id_cache_replace(coll_id, &replaced_id) != 0)<br>
>            panic("Out of memory on insertion into collation cache");<br>
>    assert(replaced_id == NULL);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
>   * A trigger invoked on replace in a space containing<br>
>   * collations that a user defined.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_replace_dd_collation(struct trigger * /* trigger */, void *event)<br>
>  {<br>
>    struct txn *txn = (struct txn *) event;<br>
> @@ -3160,6 +3182,7 @@ on_replace_dd_collation(struct trigger * /* trigger */, void *event)<br>
>            assert(new_tuple != NULL && old_tuple != NULL);<br>
>            tnt_raise(ClientError, ER_UNSUPPORTED, "collation", "alter");<br>
>    }<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -3366,7 +3389,7 @@ grant_or_revoke(struct priv_def *priv)<br>
>  }<br>
>  <br>
>  /** A trigger called on rollback of grant. */<br>
> -static void<br>
> +static int<br>
>  revoke_priv(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) event;<br>
> @@ -3375,10 +3398,11 @@ revoke_priv(struct trigger *trigger, void *event)<br>
>    priv_def_create_from_tuple(&priv, tuple);<br>
>    priv.access = 0;<br>
>    grant_or_revoke(&priv);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /** A trigger called on rollback of revoke or modify. */<br>
> -static void<br>
> +static int<br>
>  modify_priv(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) event;<br>
> @@ -3386,13 +3410,14 @@ modify_priv(struct trigger *trigger, void *event)<br>
>    struct priv_def priv;<br>
>    priv_def_create_from_tuple(&priv, tuple);<br>
>    grant_or_revoke(&priv);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
>   * A trigger invoked on replace in the space containing<br>
>   * all granted privileges.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_replace_dd_priv(struct trigger * /* trigger */, void *event)<br>
>  {<br>
>    struct txn *txn = (struct txn *) event;<br>
> @@ -3425,6 +3450,7 @@ on_replace_dd_priv(struct trigger * /* trigger */, void *event)<br>
>                    txn_alter_trigger_new(modify_priv, old_tuple);<br>
>            txn_stmt_on_rollback(stmt, on_rollback);<br>
>    }<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /* }}} access control */<br>
> @@ -3440,7 +3466,7 @@ on_replace_dd_priv(struct trigger * /* trigger */, void *event)<br>
>   * concern us, we can safely change the cluster id in before-replace<br>
>   * event, not in after-replace event.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_replace_dd_schema(struct trigger * /* trigger */, void *event)<br>
>  {<br>
>    struct txn *txn = (struct txn *) event;<br>
> @@ -3457,6 +3483,7 @@ on_replace_dd_schema(struct trigger * /* trigger */, void *event)<br>
>            REPLICASET_UUID = uu;<br>
>            say_info("cluster uuid %s", tt_uuid_str(&uu));<br>
>    }<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -3464,7 +3491,7 @@ on_replace_dd_schema(struct trigger * /* trigger */, void *event)<br>
>   * write ahead log. Update the cluster configuration cache<br>
>   * with it.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  register_replica(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    struct tuple *new_tuple = (struct tuple *)trigger->data;<br>
> @@ -3483,9 +3510,10 @@ register_replica(struct trigger *trigger, void * /* event */)<br>
>                    panic("Can't register replica: %s", e->errmsg);<br>
>            }<br>
>    }<br>
> +  return 0;<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  unregister_replica(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    struct tuple *old_tuple = (struct tuple *)trigger->data;<br>
> @@ -3496,6 +3524,7 @@ unregister_replica(struct trigger *trigger, void * /* event */)<br>
>    struct replica *replica = replica_by_uuid(&old_uuid);<br>
>    assert(replica != NULL);<br>
>    replica_clear_id(replica);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -3516,7 +3545,7 @@ unregister_replica(struct trigger *trigger, void * /* event */)<br>
>   * replica set can not by mistake join/follow another replica<br>
>   * set without first being reset (emptied).<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_replace_dd_cluster(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) trigger;<br>
> @@ -3570,6 +3599,7 @@ on_replace_dd_cluster(struct trigger *trigger, void *event)<br>
>                                              old_tuple);<br>
>            txn_stmt_on_commit(stmt, on_commit);<br>
>    }<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /* }}} cluster configuration */<br>
> @@ -3617,7 +3647,7 @@ sequence_def_new_from_tuple(struct tuple *tuple, uint32_t errcode)<br>
>    return def;<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  on_create_sequence_rollback(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    /* Remove the new sequence from the cache and delete it. */<br>
> @@ -3625,35 +3655,39 @@ on_create_sequence_rollback(struct trigger *trigger, void * /* event */)<br>
>    sequence_cache_delete(seq->def->id);<br>
>    trigger_run_xc(&on_alter_sequence, seq);<br>
>    sequence_delete(seq);<br>
> +  return 0;<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  on_drop_sequence_commit(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    /* Delete the old sequence. */<br>
>    struct sequence *seq = (struct sequence *)trigger->data;<br>
>    sequence_delete(seq);<br>
> +  return 0;<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  on_drop_sequence_rollback(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    /* Insert the old sequence back into the cache. */<br>
>    struct sequence *seq = (struct sequence *)trigger->data;<br>
>    sequence_cache_insert(seq);<br>
>    trigger_run_xc(&on_alter_sequence, seq);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  <br>
> -static void<br>
> +static int<br>
>  on_alter_sequence_commit(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    /* Delete the old old sequence definition. */<br>
>    struct sequence_def *def = (struct sequence_def *)trigger->data;<br>
>    free(def);<br>
> +  return 0;<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  on_alter_sequence_rollback(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    /* Restore the old sequence definition. */<br>
> @@ -3663,13 +3697,14 @@ on_alter_sequence_rollback(struct trigger *trigger, void * /* event */)<br>
>    free(seq->def);<br>
>    seq->def = def;<br>
>    trigger_run_xc(&on_alter_sequence, seq);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
>   * A trigger invoked on replace in space _sequence.<br>
>   * Used to alter a sequence definition.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_replace_dd_sequence(struct trigger * /* trigger */, void *event)<br>
>  {<br>
>    struct txn *txn = (struct txn *) event;<br>
> @@ -3733,10 +3768,11 @@ on_replace_dd_sequence(struct trigger * /* trigger */, void *event)<br>
>  <br>
>    def_guard.is_active = false;<br>
>    trigger_run_xc(&on_alter_sequence, seq);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /** Restore the old sequence value on rollback. */<br>
> -static void<br>
> +static int<br>
>  on_drop_sequence_data_rollback(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    struct tuple *tuple = (struct tuple *)trigger->data;<br>
> @@ -3747,13 +3783,14 @@ on_drop_sequence_data_rollback(struct trigger *trigger, void * /* event */)<br>
>    assert(seq != NULL);<br>
>    if (sequence_set(seq, val) != 0)<br>
>            panic("Can't restore sequence value");<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
>   * A trigger invoked on replace in space _sequence_data.<br>
>   * Used to update a sequence value.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_replace_dd_sequence_data(struct trigger * /* trigger */, void *event)<br>
>  {<br>
>    struct txn *txn = (struct txn *) event;<br>
> @@ -3784,6 +3821,7 @@ on_replace_dd_sequence_data(struct trigger * /* trigger */, void *event)<br>
>            txn_stmt_on_rollback(stmt, on_rollback);<br>
>            sequence_reset(seq);<br>
>    }<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -3825,7 +3863,7 @@ sequence_field_from_tuple(struct space *space, struct tuple *tuple,<br>
>  }<br>
>  <br>
>  /** Attach a sequence to a space on rollback in _space_sequence. */<br>
> -static void<br>
> +static int<br>
>  set_space_sequence(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    struct tuple *tuple = (struct tuple *)trigger->data;<br>
> @@ -3847,10 +3885,11 @@ set_space_sequence(struct trigger *trigger, void * /* event */)<br>
>    free(space->sequence_path);<br>
>    space->sequence_path = path;<br>
>    trigger_run_xc(&on_alter_space, space);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /** Detach a sequence from a space on rollback in _space_sequence. */<br>
> -static void<br>
> +static int<br>
>  clear_space_sequence(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    struct tuple *tuple = (struct tuple *)trigger->data;<br>
> @@ -3865,13 +3904,14 @@ clear_space_sequence(struct trigger *trigger, void * /* event */)<br>
>    free(space->sequence_path);<br>
>    space->sequence_path = NULL;<br>
>    trigger_run_xc(&on_alter_space, space);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
>   * A trigger invoked on replace in space _space_sequence.<br>
>   * Used to update space <-> sequence mapping.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_replace_dd_space_sequence(struct trigger * /* trigger */, void *event)<br>
>  {<br>
>    struct txn *txn = (struct txn *) event;<br>
> @@ -3950,12 +3990,13 @@ on_replace_dd_space_sequence(struct trigger * /* trigger */, void *event)<br>
>            txn_stmt_on_rollback(stmt, on_rollback);<br>
>    }<br>
>    trigger_run_xc(&on_alter_space, space);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /* }}} sequence */<br>
>  <br>
>  /** Delete the new trigger on rollback of an INSERT statement. */<br>
> -static void<br>
> +static int<br>
>  on_create_trigger_rollback(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    struct sql_trigger *old_trigger = (struct sql_trigger *)trigger->data;<br>
> @@ -3967,28 +4008,30 @@ on_create_trigger_rollback(struct trigger *trigger, void * /* event */)<br>
>    assert(rc == 0);<br>
>    assert(new_trigger == old_trigger);<br>
>    sql_trigger_delete(sql_get(), new_trigger);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /** Restore the old trigger on rollback of a DELETE statement. */<br>
> -static void<br>
> +static int<br>
>  on_drop_trigger_rollback(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    struct sql_trigger *old_trigger = (struct sql_trigger *)trigger->data;<br>
>    struct sql_trigger *new_trigger;<br>
>    if (old_trigger == NULL)<br>
> -          return;<br>
> +          return 0;<br>
>    if (sql_trigger_replace(sql_trigger_name(old_trigger),<br>
>                            sql_trigger_space_id(old_trigger),<br>
>                            old_trigger, &new_trigger) != 0)<br>
>            panic("Out of memory on insertion into trigger hash");<br>
>    assert(new_trigger == NULL);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
>   * Restore the old trigger and delete the new trigger on rollback<br>
>   * of a REPLACE statement.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_replace_trigger_rollback(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    struct sql_trigger *old_trigger = (struct sql_trigger *)trigger->data;<br>
> @@ -3998,24 +4041,26 @@ on_replace_trigger_rollback(struct trigger *trigger, void * /* event */)<br>
>                            old_trigger, &new_trigger) != 0)<br>
>            panic("Out of memory on insertion into trigger hash");<br>
>    sql_trigger_delete(sql_get(), new_trigger);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
>   * Trigger invoked on commit in the _trigger space.<br>
>   * Drop useless old sql_trigger AST object if any.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_replace_trigger_commit(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    struct sql_trigger *old_trigger = (struct sql_trigger *)trigger->data;<br>
>    sql_trigger_delete(sql_get(), old_trigger);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
>   * A trigger invoked on replace in a space containing<br>
>   * SQL triggers.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_replace_dd_trigger(struct trigger * /* trigger */, void *event)<br>
>  {<br>
>    struct txn *txn = (struct txn *) event;<br>
> @@ -4110,6 +4155,7 @@ on_replace_dd_trigger(struct trigger * /* trigger */, void *event)<br>
>  <br>
>    txn_stmt_on_rollback(stmt, on_rollback);<br>
>    txn_stmt_on_commit(stmt, on_commit);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -4303,7 +4349,7 @@ space_reset_fk_constraint_mask(struct space *space)<br>
>   * from parent's and child's lists of constraints and<br>
>   * release memory.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_create_fk_constraint_rollback(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) event;<br>
> @@ -4313,10 +4359,11 @@ on_create_fk_constraint_rollback(struct trigger *trigger, void *event)<br>
>    space_reset_fk_constraint_mask(space_by_id(fk->def->parent_id));<br>
>    space_reset_fk_constraint_mask(space_by_id(fk->def->child_id));<br>
>    fk_constraint_delete(fk);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /** Return old FK and release memory for the new one. */<br>
> -static void<br>
> +static int<br>
>  on_replace_fk_constraint_rollback(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) event;<br>
> @@ -4331,10 +4378,11 @@ on_replace_fk_constraint_rollback(struct trigger *trigger, void *event)<br>
>    rlist_add_entry(&parent->parent_fk_constraint, old_fk, in_parent_space);<br>
>    space_reset_fk_constraint_mask(parent);<br>
>    space_reset_fk_constraint_mask(child);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /** On rollback of drop simply return back FK to DD. */<br>
> -static void<br>
> +static int<br>
>  on_drop_fk_constraint_rollback(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) event;<br>
> @@ -4347,6 +4395,7 @@ on_drop_fk_constraint_rollback(struct trigger *trigger, void *event)<br>
>                           FIELD_LINK_CHILD);<br>
>    fk_constraint_set_mask(old_fk, &parent->fk_constraint_mask,<br>
>                           FIELD_LINK_PARENT);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -4354,11 +4403,12 @@ on_drop_fk_constraint_rollback(struct trigger *trigger, void *event)<br>
>   * foreign key entry from both (parent's and child's) lists,<br>
>   * so just release memory.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  on_drop_or_replace_fk_constraint_commit(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) event;<br>
>    fk_constraint_delete((struct fk_constraint *) trigger->data);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -4397,7 +4447,7 @@ error:<br>
>  }<br>
>  <br>
>  /** A trigger invoked on replace in the _fk_constraint space. */<br>
> -static void<br>
> +static int<br>
>  on_replace_dd_fk_constraint(struct trigger * /* trigger*/, void *event)<br>
>  {<br>
>    struct txn *txn = (struct txn *) event;<br>
> @@ -4565,6 +4615,7 @@ on_replace_dd_fk_constraint(struct trigger * /* trigger*/, void *event)<br>
>            space_reset_fk_constraint_mask(child_space);<br>
>            space_reset_fk_constraint_mask(parent_space);<br>
>    }<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /** Create an instance of check constraint definition by tuple. */<br>
> @@ -4604,7 +4655,7 @@ ck_constraint_def_new_from_tuple(struct tuple *tuple)<br>
>  }<br>
>  <br>
>  /** Rollback INSERT check constraint. */<br>
> -static void<br>
> +static int<br>
>  on_create_ck_constraint_rollback(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    struct ck_constraint *ck = (struct ck_constraint *)trigger->data;<br>
> @@ -4616,19 +4667,21 @@ on_create_ck_constraint_rollback(struct trigger *trigger, void * /* event */)<br>
>    space_remove_ck_constraint(space, ck);<br>
>    ck_constraint_delete(ck);<br>
>    trigger_run_xc(&on_alter_space, space);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /** Commit DELETE check constraint. */<br>
> -static void<br>
> +static int<br>
>  on_drop_ck_constraint_commit(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    struct ck_constraint *ck = (struct ck_constraint *)trigger->data;<br>
>    assert(ck != NULL);<br>
>    ck_constraint_delete(ck);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /** Rollback DELETE check constraint. */<br>
> -static void<br>
> +static int<br>
>  on_drop_ck_constraint_rollback(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    struct ck_constraint *ck = (struct ck_constraint *)trigger->data;<br>
> @@ -4640,19 +4693,21 @@ on_drop_ck_constraint_rollback(struct trigger *trigger, void * /* event */)<br>
>    if (space_add_ck_constraint(space, ck) != 0)<br>
>            panic("Can't recover after CK constraint drop rollback");<br>
>    trigger_run_xc(&on_alter_space, space);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /** Commit REPLACE check constraint. */<br>
> -static void<br>
> +static int<br>
>  on_replace_ck_constraint_commit(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    struct ck_constraint *ck = (struct ck_constraint *)trigger->data;<br>
>    if (ck != NULL)<br>
>            ck_constraint_delete(ck);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /** Rollback REPLACE check constraint. */<br>
> -static void<br>
> +static int<br>
>  on_replace_ck_constraint_rollback(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    struct ck_constraint *ck = (struct ck_constraint *)trigger->data;<br>
> @@ -4666,10 +4721,11 @@ on_replace_ck_constraint_rollback(struct trigger *trigger, void * /* event */)<br>
>    rlist_add_entry(&space->ck_constraint, ck, link);<br>
>    ck_constraint_delete(new_ck);<br>
>    trigger_run_xc(&on_alter_space, space);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /** A trigger invoked on replace in the _ck_constraint space. */<br>
> -static void<br>
> +static int<br>
>  on_replace_dd_ck_constraint(struct trigger * /* trigger*/, void *event)<br>
>  {<br>
>    struct txn *txn = (struct txn *) event;<br>
> @@ -4754,10 +4810,11 @@ on_replace_dd_ck_constraint(struct trigger * /* trigger*/, void *event)<br>
>    txn_stmt_on_commit(stmt, on_commit);<br>
>  <br>
>    trigger_run_xc(&on_alter_space, space);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /** A trigger invoked on replace in the _func_index space. */<br>
> -static void<br>
> +static int<br>
>  on_replace_dd_func_index(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) trigger;<br>
> @@ -4805,7 +4862,7 @@ on_replace_dd_func_index(struct trigger *trigger, void *event)<br>
>     * function. Index rebuild is not required.<br>
>     */<br>
>    if (index_def_get_func(index->def) == func)<br>
> -          return;<br>
> +          return 0;<br>
>  <br>
>    alter = alter_space_new(space);<br>
>    auto scoped_guard = make_scoped_guard([=] {alter_space_delete(alter);});<br>
> @@ -4818,6 +4875,7 @@ on_replace_dd_func_index(struct trigger *trigger, void *event)<br>
>    alter_space_do(stmt, alter);<br>
>  <br>
>    scoped_guard.is_active = false;<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  struct trigger alter_space_on_replace_space = {<br>
> diff --git a/src/box/applier.cc b/src/box/applier.cc<br>
> index 6239fcfd3..df36007f9 100644<br>
> --- a/src/box/applier.cc<br>
> +++ b/src/box/applier.cc<br>
> @@ -611,7 +611,7 @@ applier_read_tx(struct applier *applier, struct stailq *rows)<br>
>                                next)->row.is_commit);<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  applier_txn_rollback_cb(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) trigger;<br>
> @@ -622,14 +622,16 @@ applier_txn_rollback_cb(struct trigger *trigger, void *event)<br>
>    trigger_run(&replicaset.applier.on_rollback, event);<br>
>    /* Rollback applier vclock to the committed one. */<br>
>    vclock_copy(&replicaset.applier.vclock, &replicaset.vclock);<br>
> +  return 0;<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  applier_txn_commit_cb(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) trigger;<br>
>    /* Broadcast the commit event across all appliers. */<br>
>    trigger_run(&replicaset.applier.on_commit, event);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -745,18 +747,19 @@ fail:<br>
>  /*<br>
>   * A trigger to update an applier state after a replication commit.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  applier_on_commit(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) event;<br>
>    struct applier *applier = (struct applier *)trigger->data;<br>
>    fiber_cond_signal(&applier->writer_cond);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /*<br>
>   * A trigger to update an applier state after a replication rollback.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  applier_on_rollback(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) event;<br>
> @@ -768,6 +771,7 @@ applier_on_rollback(struct trigger *trigger, void *event)<br>
>    }<br>
>    /* Stop the applier fiber. */<br>
>    fiber_cancel(applier->reader);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -1131,7 +1135,7 @@ struct applier_on_state {<br>
>    struct fiber_cond wakeup;<br>
>  };<br>
>  <br>
> -static void<br>
> +static int<br>
>  applier_on_state_f(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) event;<br>
> @@ -1143,12 +1147,13 @@ applier_on_state_f(struct trigger *trigger, void *event)<br>
>    if (applier->state != APPLIER_OFF &&<br>
>        applier->state != APPLIER_STOPPED &&<br>
>        applier->state != on_state->desired_state)<br>
> -          return;<br>
> +          return 0;<br>
>  <br>
>    /* Wake up waiter */<br>
>    fiber_cond_signal(&on_state->wakeup);<br>
>  <br>
>    applier_pause(applier);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  static inline void<br>
> diff --git a/src/box/ck_constraint.c b/src/box/ck_constraint.c<br>
> index 1cde27022..2e0fa24a5 100644<br>
> --- a/src/box/ck_constraint.c<br>
> +++ b/src/box/ck_constraint.c<br>
> @@ -175,7 +175,7 @@ ck_constraint_program_run(struct ck_constraint *ck_constraint,<br>
>    return sql_reset(ck_constraint->stmt);<br>
>  }<br>
>  <br>
> -void<br>
> +int<br>
>  ck_constraint_on_replace_trigger(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) trigger;<br>
> @@ -184,7 +184,7 @@ ck_constraint_on_replace_trigger(struct trigger *trigger, void *event)<br>
>    assert(stmt != NULL);<br>
>    struct tuple *new_tuple = stmt->new_tuple;<br>
>    if (new_tuple == NULL)<br>
> -          return;<br>
> +          return 0;<br>
>  <br>
>    struct space *space = stmt->space;<br>
>    assert(space != NULL);<br>
> @@ -195,15 +195,16 @@ ck_constraint_on_replace_trigger(struct trigger *trigger, void *event)<br>
>    if (field_ref == NULL) {<br>
>            diag_set(OutOfMemory, field_ref_sz, "region_alloc",<br>
>                     "field_ref");<br>
> -          diag_raise();<br>
> +          return -1;<br>
>    }<br>
>    vdbe_field_ref_prepare_tuple(field_ref, new_tuple);<br>
>  <br>
>    struct ck_constraint *ck_constraint;<br>
>    rlist_foreach_entry(ck_constraint, &space->ck_constraint, link) {<br>
>            if (ck_constraint_program_run(ck_constraint, field_ref) != 0)<br>
> -                  diag_raise();<br>
> +                  return -1;<br>
>    }<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  struct ck_constraint *<br>
> diff --git a/src/box/ck_constraint.h b/src/box/ck_constraint.h<br>
> index f26f77a38..2c27a839a 100644<br>
> --- a/src/box/ck_constraint.h<br>
> +++ b/src/box/ck_constraint.h<br>
> @@ -195,10 +195,10 @@ ck_constraint_delete(struct ck_constraint *ck_constraint);<br>
>   * pointer to make ck constraint independent of specific space<br>
>   * object version.<br>
>   *<br>
> - * Raises an exception when some ck constraint is unsatisfied.<br>
> + * Returns error code when some ck constraint is unsatisfied.<br>
>   * The diag message is set.<br>
>   */<br>
> -void<br>
> +int<br>
>  ck_constraint_on_replace_trigger(struct trigger *trigger, void *event);<br>
>  <br>
>  /**<br>
> diff --git a/src/box/iproto.cc b/src/box/iproto.cc<br>
> index 8f899fed8..34c8f469a 100644<br>
> --- a/src/box/iproto.cc<br>
> +++ b/src/box/iproto.cc<br>
> @@ -1505,7 +1505,7 @@ error:<br>
>    tx_reply_error(msg);<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  tx_process_call_on_yield(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void)event;<br>
> @@ -1513,6 +1513,7 @@ tx_process_call_on_yield(struct trigger *trigger, void *event)<br>
>    TRASH(&msg->call);<br>
>    tx_discard_input(msg);<br>
>    trigger_clear(trigger);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  static void<br>
> diff --git a/src/box/lua/call.c b/src/box/lua/call.c<br>
> index 631003c84..2612c5c63 100644<br>
> --- a/src/box/lua/call.c<br>
> +++ b/src/box/lua/call.c<br>
> @@ -952,17 +952,18 @@ lbox_func_delete(struct lua_State *L, struct func *func)<br>
>    lua_pop(L, 2); /* box, func */<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  lbox_func_new_or_delete(struct trigger *trigger, void *event)<br>
>  {<br>
>    struct lua_State *L = (struct lua_State *) trigger->data;<br>
>    struct func *func = (struct func *)event;<br>
>    if (!func->def->exports.lua)<br>
> -          return;<br>
> +          return 0;<br>
>    if (func_by_id(func->def->fid) != NULL)<br>
>            lbox_func_new(L, func);<br>
>    else<br>
>            lbox_func_delete(L, func);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  static struct trigger on_alter_func_in_lua = {<br>
> diff --git a/src/box/lua/sequence.c b/src/box/lua/sequence.c<br>
> index bd9ec7589..bf0714c1a 100644<br>
> --- a/src/box/lua/sequence.c<br>
> +++ b/src/box/lua/sequence.c<br>
> @@ -157,7 +157,7 @@ lbox_sequence_delete(struct lua_State *L, struct sequence *seq)<br>
>    lua_pop(L, 2); /* box, sequence */<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  lbox_sequence_new_or_delete(struct trigger *trigger, void *event)<br>
>  {<br>
>    struct lua_State *L = trigger->data;<br>
> @@ -166,6 +166,7 @@ lbox_sequence_new_or_delete(struct trigger *trigger, void *event)<br>
>            lbox_sequence_new(L, seq);<br>
>    else<br>
>            lbox_sequence_delete(L, seq);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  void<br>
> diff --git a/src/box/lua/space.cc b/src/box/lua/space.cc<br>
> index d0a7e7815..ea8294f95 100644<br>
> --- a/src/box/lua/space.cc<br>
> +++ b/src/box/lua/space.cc<br>
> @@ -500,7 +500,7 @@ box_lua_space_delete(struct lua_State *L, uint32_t id)<br>
>    lua_pop(L, 2); /* box, space */<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  box_lua_space_new_or_delete(struct trigger *trigger, void *event)<br>
>  {<br>
>    struct lua_State *L = (struct lua_State *) trigger->data;<br>
> @@ -511,6 +511,7 @@ box_lua_space_new_or_delete(struct trigger *trigger, void *event)<br>
>    } else {<br>
>            box_lua_space_delete(L, space->def->id);<br>
>    }<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  static struct trigger on_alter_space_in_lua = {<br>
> diff --git a/src/box/memtx_space.c b/src/box/memtx_space.c<br>
> index 487cfdadd..601e98ce5 100644<br>
> --- a/src/box/memtx_space.c<br>
> +++ b/src/box/memtx_space.c<br>
> @@ -834,7 +834,7 @@ struct memtx_ddl_state {<br>
>    int rc;<br>
>  };<br>
>  <br>
> -static void<br>
> +static int<br>
>  memtx_check_on_replace(struct trigger *trigger, void *event)<br>
>  {<br>
>    struct txn *txn = event;<br>
> @@ -843,11 +843,11 @@ memtx_check_on_replace(struct trigger *trigger, void *event)<br>
>  <br>
>    /* Nothing to check on DELETE. */<br>
>    if (stmt->new_tuple == NULL)<br>
> -          return;<br>
> +          return 0;<br>
>  <br>
>    /* We have already failed. */<br>
>    if (state->rc != 0)<br>
> -          return;<br>
> +          return 0;<br>
>  <br>
>    /*<br>
>     * Only check format for already processed part of the space,<br>
> @@ -856,11 +856,12 @@ memtx_check_on_replace(struct trigger *trigger, void *event)<br>
>     */<br>
>    if (tuple_compare(state->cursor, HINT_NONE, stmt->new_tuple, HINT_NONE,<br>
>                      state->cmp_def) < 0)<br>
> -          return;<br>
> +          return 0;<br>
>  <br>
>    state->rc = tuple_validate(state->format, stmt->new_tuple);<br>
>    if (state->rc != 0)<br>
>            diag_move(diag_get(), &state->diag);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  static int<br>
> @@ -957,7 +958,7 @@ memtx_init_ephemeral_space(struct space *space)<br>
>    memtx_space_add_primary_key(space);<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  memtx_build_on_replace(struct trigger *trigger, void *event)<br>
>  {<br>
>    struct txn *txn = event;<br>
> @@ -972,13 +973,13 @@ memtx_build_on_replace(struct trigger *trigger, void *event)<br>
>     */<br>
>    if (tuple_compare(state->cursor, HINT_NONE, cmp_tuple, HINT_NONE,<br>
>                      state->cmp_def) < 0)<br>
> -          return;<br>
> +          return 0;<br>
>  <br>
>    if (stmt->new_tuple != NULL &&<br>
>        tuple_validate(state->format, stmt->new_tuple) != 0) {<br>
>            state->rc = -1;<br>
>            diag_move(diag_get(), &state->diag);<br>
> -          return;<br>
> +          return 0;<br>
>    }<br>
>  <br>
>    struct tuple *delete = NULL;<br>
> @@ -991,7 +992,7 @@ memtx_build_on_replace(struct trigger *trigger, void *event)<br>
>    if (state->rc != 0) {<br>
>            diag_move(diag_get(), &state->diag);<br>
>    }<br>
> -  return;<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  static int<br>
> diff --git a/src/box/relay.cc b/src/box/relay.cc<br>
> index 74588cba7..e849fcf4f 100644<br>
> --- a/src/box/relay.cc<br>
> +++ b/src/box/relay.cc<br>
> @@ -411,7 +411,7 @@ tx_gc_advance(struct cmsg *msg)<br>
>    free(m);<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  relay_on_close_log_f(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    static const struct cmsg_hop route[] = {<br>
> @@ -421,7 +421,7 @@ relay_on_close_log_f(struct trigger *trigger, void * /* event */)<br>
>    struct relay_gc_msg *m = (struct relay_gc_msg *)malloc(sizeof(*m));<br>
>    if (m == NULL) {<br>
>            say_warn("failed to allocate relay gc message");<br>
> -          return;<br>
> +          return 0;<br>
>    }<br>
>    cmsg_init(&m->msg, route);<br>
>    m->relay = relay;<br>
> @@ -432,6 +432,7 @@ relay_on_close_log_f(struct trigger *trigger, void * /* event */)<br>
>     * sent xlog.<br>
>     */<br>
>    stailq_add_tail_entry(&relay->pending_gc, m, in_pending);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> diff --git a/src/box/replication.cc b/src/box/replication.cc<br>
> index d691ce487..030221457 100644<br>
> --- a/src/box/replication.cc<br>
> +++ b/src/box/replication.cc<br>
> @@ -147,7 +147,7 @@ replica_is_orphan(struct replica *replica)<br>
>           relay_get_state(replica->relay) != RELAY_FOLLOW;<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  replica_on_applier_state_f(struct trigger *trigger, void *event);<br>
>  <br>
>  static struct replica *<br>
> @@ -401,7 +401,7 @@ replica_on_applier_disconnect(struct replica *replica)<br>
>            replicaset.applier.loading++;<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  replica_on_applier_state_f(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void)event;<br>
> @@ -443,6 +443,7 @@ replica_on_applier_state_f(struct trigger *trigger, void *event)<br>
>            break;<br>
>    }<br>
>    fiber_cond_signal(&replicaset.applier.cond);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -575,7 +576,7 @@ struct applier_on_connect {<br>
>    struct replicaset_connect_state *state;<br>
>  };<br>
>  <br>
> -static void<br>
> +static int<br>
>  applier_on_connect_f(struct trigger *trigger, void *event)<br>
>  {<br>
>    struct applier_on_connect *on_connect = container_of(trigger,<br>
> @@ -592,10 +593,11 @@ applier_on_connect_f(struct trigger *trigger, void *event)<br>
>            state->connected++;<br>
>            break;<br>
>    default:<br>
> -          return;<br>
> +          return 0;<br>
>    }<br>
>    fiber_cond_signal(&state->wakeup);<br>
>    applier_pause(applier);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  void<br>
> diff --git a/src/box/session.cc b/src/box/session.cc<br>
> index 59bf226dd..d69b6572f 100644<br>
> --- a/src/box/session.cc<br>
> +++ b/src/box/session.cc<br>
> @@ -80,7 +80,7 @@ sid_max()<br>
>    return sid_max;<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  session_on_stop(struct trigger *trigger, void * /* event */)<br>
>  {<br>
>    /*<br>
> @@ -91,6 +91,7 @@ session_on_stop(struct trigger *trigger, void * /* event */)<br>
>    trigger_clear(trigger);<br>
>    /* Destroy the session */<br>
>    session_destroy(fiber_get_session(fiber()));<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  static int<br>
> diff --git a/src/box/txn.c b/src/box/txn.c<br>
> index 38b1b595f..963ec8eeb 100644<br>
> --- a/src/box/txn.c<br>
> +++ b/src/box/txn.c<br>
> @@ -40,10 +40,10 @@ double too_long_threshold;<br>
>  /* Txn cache. */<br>
>  static struct stailq txn_cache = {NULL, &txn_cache.first};<br>
>  <br>
> -static void<br>
> +static int<br>
>  txn_on_stop(struct trigger *trigger, void *event);<br>
>  <br>
> -static void<br>
> +static int<br>
>  txn_on_yield(struct trigger *trigger, void *event);<br>
>  <br>
>  static void<br>
> @@ -839,12 +839,13 @@ txn_savepoint_release(struct txn_savepoint *svp)<br>
>    rlist_cut_before(&discard, &txn->savepoints, rlist_next(&svp->link));<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  txn_on_stop(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) trigger;<br>
>    (void) event;<br>
>    txn_rollback(in_txn());                 /* doesn't yield or fail */<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -864,7 +865,7 @@ txn_on_stop(struct trigger *trigger, void *event)<br>
>   * So much hassle to be user-friendly until we have a true<br>
>   * interactive transaction support in memtx.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  txn_on_yield(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) trigger;<br>
> @@ -874,4 +875,5 @@ txn_on_yield(struct trigger *trigger, void *event)<br>
>    assert(!txn_has_flag(txn, TXN_CAN_YIELD));<br>
>    txn_rollback_to_svp(txn, NULL);<br>
>    txn_set_flag(txn, TXN_IS_ABORTED_BY_YIELD);<br>
> +  return 0;<br>
>  }<br>
> diff --git a/src/box/vinyl.c b/src/box/vinyl.c<br>
> index 23910795f..a2bbaa529 100644<br>
> --- a/src/box/vinyl.c<br>
> +++ b/src/box/vinyl.c<br>
> @@ -1010,7 +1010,7 @@ struct vy_check_format_ctx {<br>
>   * This is an on_replace trigger callback that checks inserted<br>
>   * tuples against a new format.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  vy_check_format_on_replace(struct trigger *trigger, void *event)<br>
>  {<br>
>    struct txn *txn = event;<br>
> @@ -1018,15 +1018,16 @@ vy_check_format_on_replace(struct trigger *trigger, void *event)<br>
>    struct vy_check_format_ctx *ctx = trigger->data;<br>
>  <br>
>    if (stmt->new_tuple == NULL)<br>
> -          return; /* DELETE, nothing to do */<br>
> +          return 0; /* DELETE, nothing to do */<br>
>  <br>
>    if (ctx->is_failed)<br>
> -          return; /* already failed, nothing to do */<br>
> +          return 0; /* already failed, nothing to do */<br>
>  <br>
>    if (tuple_validate(ctx->format, stmt->new_tuple) != 0) {<br>
>            ctx->is_failed = true;<br>
>            diag_move(diag_get(), &ctx->diag);<br>
>    }<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  static int<br>
> @@ -3420,13 +3421,14 @@ fail:<br>
>  <br>
>  /* {{{ Cursor */<br>
>  <br>
> -static void<br>
> +static int<br>
>  vinyl_iterator_on_tx_destroy(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void)event;<br>
>    struct vinyl_iterator *it = container_of(trigger,<br>
>                    struct vinyl_iterator, on_tx_destroy);<br>
>    it->tx = NULL;<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  static int<br>
> @@ -3791,7 +3793,7 @@ struct vy_build_ctx {<br>
>   * This is an on_replace trigger callback that forwards DML requests<br>
>   * to the index that is currently being built.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  vy_build_on_replace(struct trigger *trigger, void *event)<br>
>  {<br>
>    struct txn *txn = event;<br>
> @@ -3802,7 +3804,7 @@ vy_build_on_replace(struct trigger *trigger, void *event)<br>
>    struct vy_lsm *lsm = ctx->lsm;<br>
>  <br>
>    if (ctx->is_failed)<br>
> -          return; /* already failed, nothing to do */<br>
> +          return 0; /* already failed, nothing to do */<br>
>  <br>
>    /* Check new tuples for conformity to the new format. */<br>
>    if (stmt->new_tuple != NULL &&<br>
> @@ -3839,7 +3841,7 @@ vy_build_on_replace(struct trigger *trigger, void *event)<br>
>            if (rc != 0)<br>
>                    goto err;<br>
>    }<br>
> -  return;<br>
> +  return 0;<br>
>  err:<br>
>    /*<br>
>     * No need to abort the DDL request if this transaction<br>
> @@ -3849,9 +3851,10 @@ err:<br>
>     * context isn't valid and so we must not modify it.<br>
>     */<br>
>    if (tx->state == VINYL_TX_ABORT)<br>
> -          return;<br>
> +          return 0;<br>
>    ctx->is_failed = true;<br>
>    diag_move(diag_get(), &ctx->diag);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -4247,7 +4250,7 @@ out:<br>
>  <br>
>  /* {{{ Deferred DELETE handling */<br>
>  <br>
> -static void<br>
> +static int<br>
>  vy_deferred_delete_on_commit(struct trigger *trigger, void *event)<br>
>  {<br>
>    struct txn *txn = event;<br>
> @@ -4260,15 +4263,17 @@ vy_deferred_delete_on_commit(struct trigger *trigger, void *event)<br>
>    mem->dump_lsn = txn->signature;<br>
>    /* Unpin the mem pinned in vy_deferred_delete_on_replace(). */<br>
>    vy_mem_unpin(mem);<br>
> +  return 0;<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  vy_deferred_delete_on_rollback(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void)event;<br>
>    struct vy_mem *mem = trigger->data;<br>
>    /* Unpin the mem pinned in vy_deferred_delete_on_replace(). */<br>
>    vy_mem_unpin(mem);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -4295,7 +4300,7 @@ vy_deferred_delete_on_rollback(struct trigger *trigger, void *event)<br>
>   * one of the trees got dumped while the other didn't, we would<br>
>   * mistakenly skip both statements on recovery.<br>
>   */<br>
> -static void<br>
> +static int<br>
>  vy_deferred_delete_on_replace(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void)trigger;<br>
> @@ -4305,7 +4310,7 @@ vy_deferred_delete_on_replace(struct trigger *trigger, void *event)<br>
>    bool is_first_statement = txn_is_first_statement(txn);<br>
>  <br>
>    if (stmt->new_tuple == NULL)<br>
> -          return;<br>
> +          return 0;<br>
>    /*<br>
>     * Extract space id, LSN of the deferred DELETE statement,<br>
>     * and the deleted tuple from the system space row.<br>
> @@ -4314,27 +4319,27 @@ vy_deferred_delete_on_replace(struct trigger *trigger, void *event)<br>
>    tuple_rewind(&it, stmt->new_tuple);<br>
>    uint32_t space_id;<br>
>    if (tuple_next_u32(&it, &space_id) != 0)<br>
> -          diag_raise();<br>
> +          return -1;<br>
>    uint64_t lsn;<br>
>    if (tuple_next_u64(&it, &lsn) != 0)<br>
> -          diag_raise();<br>
> +          return -1;<br>
>    const char *delete_data = tuple_next_with_type(&it, MP_ARRAY);<br>
>    if (delete_data == NULL)<br>
> -          diag_raise();<br>
> +          return -1;<br>
>    const char *delete_data_end = delete_data;<br>
>    mp_next(&delete_data_end);<br>
>  <br>
>    /* Look up the space. */<br>
>    struct space *space = space_cache_find(space_id);<br>
>    if (space == NULL)<br>
> -          diag_raise();<br>
> +          return -1;<br>
>    /*<br>
>     * All secondary indexes could have been dropped, in<br>
>     * which case we don't need to generate deferred DELETE<br>
>     * statements anymore.<br>
>     */<br>
>    if (space->index_count <= 1)<br>
> -          return;<br>
> +          return 0;<br>
>    /*<br>
>     * Wait for memory quota if necessary before starting to<br>
>     * process the batch (we can't yield between statements).<br>
> @@ -4348,7 +4353,7 @@ vy_deferred_delete_on_replace(struct trigger *trigger, void *event)<br>
>    struct tuple *delete = vy_stmt_new_delete(pk->mem_format, delete_data,<br>
>                                              delete_data_end);<br>
>    if (delete == NULL)<br>
> -          diag_raise();<br>
> +          return -1;<br>
>    /*<br>
>     * A deferred DELETE may be generated after new statements<br>
>     * were committed for the deleted key. So we must use the<br>
> @@ -4440,7 +4445,8 @@ vy_deferred_delete_on_replace(struct trigger *trigger, void *event)<br>
>  <br>
>    tuple_unref(delete);<br>
>    if (rc != 0)<br>
> -          diag_raise();<br>
> +          return -1;<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  static struct trigger on_replace_vinyl_deferred_delete = {<br>
> diff --git a/src/box/vy_scheduler.c b/src/box/vy_scheduler.c<br>
> index ee361c31f..86bed8013 100644<br>
> --- a/src/box/vy_scheduler.c<br>
> +++ b/src/box/vy_scheduler.c<br>
> @@ -510,7 +510,7 @@ vy_scheduler_reset_stat(struct vy_scheduler *scheduler)<br>
>    stat->compaction_output = 0;<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  vy_scheduler_on_delete_lsm(struct trigger *trigger, void *event)<br>
>  {<br>
>    struct vy_lsm *lsm = event;<br>
> @@ -521,6 +521,7 @@ vy_scheduler_on_delete_lsm(struct trigger *trigger, void *event)<br>
>    vy_compaction_heap_delete(&scheduler->compaction_heap, lsm);<br>
>    trigger_clear(trigger);<br>
>    free(trigger);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  int<br>
> diff --git a/src/lib/core/fiber.c b/src/lib/core/fiber.c<br>
> index ce90f930c..7f50815ec 100644<br>
> --- a/src/lib/core/fiber.c<br>
> +++ b/src/lib/core/fiber.c<br>
> @@ -1292,12 +1292,13 @@ cord_cojoin(struct cord *cord)<br>
>    return cord_join(cord);<br>
>  }<br>
>  <br>
> -void<br>
> +int<br>
>  break_ev_loop_f(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) trigger;<br>
>    (void) event;<br>
>    ev_break(loop(), EVBREAK_ALL);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  struct costart_ctx<br>
> diff --git a/src/lib/core/trigger.cc b/src/lib/core/trigger.cc<br>
> index 4a43151e1..8f6a83fb5 100644<br>
> --- a/src/lib/core/trigger.cc<br>
> +++ b/src/lib/core/trigger.cc<br>
> @@ -38,7 +38,8 @@ trigger_run(struct rlist *list, void *event)<br>
>    try {<br>
>            struct trigger *trigger, *tmp;<br>
>            rlist_foreach_entry_safe(trigger, list, link, tmp)<br>
> -                  trigger->run(trigger, event);<br>
> +                  if (trigger->run(trigger, event) != 0)<br>
> +                          return -1;<br>
>    } catch (Exception *e) {<br>
>            return -1;<br>
>    }<br>
> @@ -51,7 +52,8 @@ trigger_run_reverse(struct rlist *list, void *event)<br>
>    try {<br>
>            struct trigger *trigger, *tmp;<br>
>            rlist_foreach_entry_safe_reverse(trigger, list, link, tmp)<br>
> -                  trigger->run(trigger, event);<br>
> +                  if (trigger->run(trigger, event) != 0)<br>
> +                          return -1;<br>
>    } catch (Exception *e) {<br>
>            return -1;<br>
>    }<br>
> diff --git a/src/lib/core/trigger.h b/src/lib/core/trigger.h<br>
> index 76fa6345d..7b500dd92 100644<br>
> --- a/src/lib/core/trigger.h<br>
> +++ b/src/lib/core/trigger.h<br>
> @@ -40,7 +40,7 @@ extern "C" {<br>
>   * on an event.<br>
>   */<br>
>  struct trigger;<br>
> -typedef void (*trigger_f)(struct trigger *trigger, void *event);<br>
> +typedef int (*trigger_f)(struct trigger *trigger, void *event);<br>
>  typedef void (*trigger_f0)(struct trigger *trigger);<br>
>  <br>
>  struct trigger<br>
> diff --git a/src/lua/trigger.c b/src/lua/trigger.c<br>
> index 4803e85c5..5ffa22e0b 100644<br>
> --- a/src/lua/trigger.c<br>
> +++ b/src/lua/trigger.c<br>
> @@ -62,7 +62,7 @@ lbox_trigger_destroy(struct trigger *ptr)<br>
>    free(ptr);<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  lbox_trigger_run(struct trigger *ptr, void *event)<br>
>  {<br>
>    struct lbox_trigger *trigger = (struct lbox_trigger *) ptr;<br>
> @@ -97,14 +97,14 @@ lbox_trigger_run(struct trigger *ptr, void *event)<br>
>    }<br>
>    if (luaT_call(L, nargs, LUA_MULTRET)) {<br>
>            luaL_unref(tarantool_L, LUA_REGISTRYINDEX, coro_ref);<br>
> -          diag_raise();<br>
> +          return -1;<br>
>    }<br>
>    int nret = lua_gettop(L) - top;<br>
>    if (trigger->pop_event != NULL &&<br>
>        trigger->pop_event(L, nret, event) != 0) {<br>
>            lua_settop(L, top);<br>
>            luaL_unref(tarantool_L, LUA_REGISTRYINDEX, coro_ref);<br>
> -          diag_raise();<br>
> +          return -1;<br>
>    }<br>
>    /*<br>
>     * Clear the stack after pop_event saves all<br>
> @@ -112,6 +112,7 @@ lbox_trigger_run(struct trigger *ptr, void *event)<br>
>     */<br>
>    lua_settop(L, top);<br>
>    luaL_unref(tarantool_L, LUA_REGISTRYINDEX, coro_ref);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  static struct lbox_trigger *<br>
> diff --git a/src/main.cc b/src/main.cc<br>
> index b16cfa5fe..da095ebf7 100644<br>
> --- a/src/main.cc<br>
> +++ b/src/main.cc<br>
> @@ -683,10 +683,11 @@ print_help(const char *program)<br>
>    puts("to see online documentation, submit bugs or contribute a patch.");<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  break_loop(struct trigger *, void *)<br>
>  {<br>
>    ev_break(loop(), EVBREAK_ALL);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  int<br>
> diff --git a/test/unit/cbus.c b/test/unit/cbus.c<br>
> index be930ab8f..ecf5fce72 100644<br>
> --- a/test/unit/cbus.c<br>
> +++ b/test/unit/cbus.c<br>
> @@ -43,13 +43,14 @@ do_nothing(struct cmsg *m)<br>
>  }<br>
>  <br>
>  /** Callback called on each flush to the main thread. */<br>
> -static void<br>
> +static int<br>
>  flush_cb(struct trigger *t, void *e)<br>
>  {<br>
>    (void) t;<br>
>    (void) e;<br>
>    ++flushed_cnt;<br>
>    printf("flush event, counter = %d\n", flushed_cnt);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /** Callback to finish the test. It breaks the main event loop. */<br>
> diff --git a/test/unit/swim.c b/test/unit/swim.c<br>
> index 1371e7d26..bb12baf8d 100644<br>
> --- a/test/unit/swim.c<br>
> +++ b/test/unit/swim.c<br>
> @@ -827,7 +827,7 @@ struct trigger_ctx {<br>
>    struct swim_on_member_event_ctx ctx;<br>
>  };<br>
>  <br>
> -static void<br>
> +static int<br>
>  swim_on_member_event_save(struct trigger *t, void *event)<br>
>  {<br>
>    struct trigger_ctx *c = (struct trigger_ctx *) t->data;<br>
> @@ -836,9 +836,10 @@ swim_on_member_event_save(struct trigger *t, void *event)<br>
>            swim_member_unref(c->ctx.member);<br>
>    c->ctx = *((struct swim_on_member_event_ctx *) event);<br>
>    swim_member_ref(c->ctx.member);<br>
> +  return 0;<br>
>  }<br>
>  <br>
> -static void<br>
> +static int<br>
>  swim_on_member_event_yield(struct trigger *t, void *event)<br>
>  {<br>
>    struct trigger_ctx *c = (struct trigger_ctx *) t->data;<br>
> @@ -846,6 +847,7 @@ swim_on_member_event_yield(struct trigger *t, void *event)<br>
>    c->f = fiber();<br>
>    while (c->need_sleep)<br>
>            fiber_yield();<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  static void<br>
> diff --git a/test/unit/swim_test_utils.c b/test/unit/swim_test_utils.c<br>
> index 7da82d93c..9dbd28a9f 100644<br>
> --- a/test/unit/swim_test_utils.c<br>
> +++ b/test/unit/swim_test_utils.c<br>
> @@ -176,7 +176,7 @@ swim_cluster_id_to_uri(char *buffer, int id)<br>
>   * A trigger to check correctness of event context, and ability<br>
>   * to yield.<br>
>   */<br>
> -void<br>
> +int<br>
>  swim_test_event_cb(struct trigger *trigger, void *event)<br>
>  {<br>
>    (void) trigger;<br>
> @@ -186,6 +186,7 @@ swim_test_event_cb(struct trigger *trigger, void *event)<br>
>    assert((ctx->events & SWIM_EV_NEW) == 0 ||<br>
>           (ctx->events & SWIM_EV_DROP) == 0);<br>
>    fiber_sleep(0);<br>
> +  return 0;<br>
>  }<br>
>  <br>
>  /** Create a SWIM cluster node @a n with a 0-based @a id. */<br>
> -- <br>
> 2.17.1<br>
> <br>
> <br>
</div>
            
        
                
        </div>

        
</div>


</div>
</blockquote>
<br>
<br>-- <br>Ilya Kosarev<br>
</div></div>
            
        
                
        </div>

        
</div>



<br><hr>
<br>-- <br>Ilya Kosarev<br><style type="text/css"></style></BODY></HTML>