blob: 6748b21e59c6b44b21f5589af348cfa2090c1a4c [file] [log] [blame]
Craig Tiller298751c2015-09-22 09:41:05 -07001/*
2 *
Craig Tiller6169d5f2016-03-31 07:46:18 -07003 * Copyright 2015, Google Inc.
Craig Tiller298751c2015-09-22 09:41:05 -07004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
Craig Tiller9a4dddd2016-03-25 17:08:13 -070034#ifndef GRPC_CORE_LIB_IOMGR_CLOSURE_H
35#define GRPC_CORE_LIB_IOMGR_CLOSURE_H
Craig Tiller298751c2015-09-22 09:41:05 -070036
Craig Tiller48db18f2015-11-02 14:14:51 -080037#include <grpc/support/port_platform.h>
Craig Tiller7cdad962016-11-10 08:37:21 -080038
39#include <grpc/impl/codegen/exec_ctx_fwd.h>
Craig Tiller6c396862016-01-28 13:53:40 -080040#include <stdbool.h>
Craig Tiller27f59af2016-04-28 14:19:48 -070041#include "src/core/lib/iomgr/error.h"
Craig Tillerf7cade12016-07-07 21:41:10 -070042#include "src/core/lib/support/mpscq.h"
Craig Tiller298751c2015-09-22 09:41:05 -070043
44struct grpc_closure;
45typedef struct grpc_closure grpc_closure;
46
Craig Tillera82950e2015-09-22 12:33:20 -070047typedef struct grpc_closure_list {
Craig Tiller298751c2015-09-22 09:41:05 -070048 grpc_closure *head;
49 grpc_closure *tail;
50} grpc_closure_list;
51
52/** gRPC Callback definition.
53 *
54 * \param arg Arbitrary input.
Craig Tiller081f1a32016-05-24 13:16:42 -070055 * \param error GRPC_ERROR_NONE if no error occurred, otherwise some grpc_error
56 * describing what went wrong */
Craig Tillera82950e2015-09-22 12:33:20 -070057typedef void (*grpc_iomgr_cb_func)(grpc_exec_ctx *exec_ctx, void *arg,
Craig Tillerc027e772016-05-03 16:27:00 -070058 grpc_error *error);
Craig Tiller298751c2015-09-22 09:41:05 -070059
Craig Tiller91031da2016-12-28 15:44:25 -080060typedef struct grpc_closure_scheduler grpc_closure_scheduler;
61
62typedef struct grpc_closure_scheduler_vtable {
63 /* NOTE: for all these functions, closure->scheduler == the scheduler that was
64 used to find this vtable */
65 void (*run)(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
66 grpc_error *error);
67 void (*sched)(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
68 grpc_error *error);
Craig Tiller7c70b6c2017-01-23 07:48:42 -080069 const char *name;
Craig Tiller91031da2016-12-28 15:44:25 -080070} grpc_closure_scheduler_vtable;
71
72/** Abstract type that can schedule closures for execution */
73struct grpc_closure_scheduler {
74 const grpc_closure_scheduler_vtable *vtable;
75};
76
Craig Tiller298751c2015-09-22 09:41:05 -070077/** A closure over a grpc_iomgr_cb_func. */
Craig Tillera82950e2015-09-22 12:33:20 -070078struct grpc_closure {
Craig Tillerf7cade12016-07-07 21:41:10 -070079 /** Once queued, next indicates the next queued closure; before then, scratch
80 * space */
81 union {
82 grpc_closure *next;
83 gpr_mpscq_node atm_next;
84 uintptr_t scratch;
85 } next_data;
86
Craig Tiller298751c2015-09-22 09:41:05 -070087 /** Bound callback. */
88 grpc_iomgr_cb_func cb;
89
90 /** Arguments to be passed to "cb". */
91 void *cb_arg;
92
Craig Tiller91031da2016-12-28 15:44:25 -080093 /** Scheduler to schedule against: NULL to schedule against current execution
94 context */
95 grpc_closure_scheduler *scheduler;
96
Craig Tiller081f1a32016-05-24 13:16:42 -070097 /** Once queued, the result of the closure. Before then: scratch space */
Craig Tillera7cd41c2016-08-31 12:59:24 -070098 union {
99 grpc_error *error;
100 uintptr_t scratch;
101 } error_data;
Craig Tiller298751c2015-09-22 09:41:05 -0700102};
103
Craig Tiller91031da2016-12-28 15:44:25 -0800104/** Initializes \a closure with \a cb and \a cb_arg. Returns \a closure. */
105grpc_closure *grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb,
106 void *cb_arg,
107 grpc_closure_scheduler *scheduler);
Craig Tiller298751c2015-09-22 09:41:05 -0700108
Craig Tiller3ff551b2015-10-06 09:11:37 -0700109/* Create a heap allocated closure: try to avoid except for very rare events */
Craig Tiller91031da2016-12-28 15:44:25 -0800110grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg,
111 grpc_closure_scheduler *scheduler);
Craig Tiller3ff551b2015-10-06 09:11:37 -0700112
Craig Tiller298751c2015-09-22 09:41:05 -0700113#define GRPC_CLOSURE_LIST_INIT \
114 { NULL, NULL }
115
Craig Tillera36857d2016-07-08 16:57:42 -0700116void grpc_closure_list_init(grpc_closure_list *list);
117
Craig Tiller081f1a32016-05-24 13:16:42 -0700118/** add \a closure to the end of \a list
119 and set \a closure's result to \a error */
Craig Tiller27f59af2016-04-28 14:19:48 -0700120void grpc_closure_list_append(grpc_closure_list *list, grpc_closure *closure,
121 grpc_error *error);
David Garcia Quintas4bc34632015-10-07 16:12:35 -0700122
Craig Tiller0ede5452016-04-23 12:21:45 -0700123/** force all success bits in \a list to false */
Craig Tiller27f59af2016-04-28 14:19:48 -0700124void grpc_closure_list_fail_all(grpc_closure_list *list,
125 grpc_error *forced_failure);
Craig Tiller0ede5452016-04-23 12:21:45 -0700126
David Garcia Quintas4bc34632015-10-07 16:12:35 -0700127/** append all closures from \a src to \a dst and empty \a src. */
Craig Tillera82950e2015-09-22 12:33:20 -0700128void grpc_closure_list_move(grpc_closure_list *src, grpc_closure_list *dst);
David Garcia Quintas4bc34632015-10-07 16:12:35 -0700129
David Garcia Quintas4bc34632015-10-07 16:12:35 -0700130/** return whether \a list is empty. */
Craig Tiller6c396862016-01-28 13:53:40 -0800131bool grpc_closure_list_empty(grpc_closure_list list);
Craig Tiller298751c2015-09-22 09:41:05 -0700132
Craig Tillerde2c41c2016-09-01 15:08:08 -0700133/** Run a closure directly. Caller ensures that no locks are being held above.
134 * Note that calling this at the end of a closure callback function itself is
135 * by definition safe. */
Craig Tiller44b12f92016-09-08 10:06:14 -0700136void grpc_closure_run(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
137 grpc_error *error);
Craig Tillerde2c41c2016-09-01 15:08:08 -0700138
Craig Tiller91031da2016-12-28 15:44:25 -0800139/** Schedule a closure to be run. Does not need to be run from a safe point. */
140void grpc_closure_sched(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
141 grpc_error *error);
142
143/** Schedule all closures in a list to be run. Does not need to be run from a
144 * safe point. */
145void grpc_closure_list_sched(grpc_exec_ctx *exec_ctx,
146 grpc_closure_list *closure_list);
147
Craig Tiller9a4dddd2016-03-25 17:08:13 -0700148#endif /* GRPC_CORE_LIB_IOMGR_CLOSURE_H */