Main Page
Modules
Data Structures
Files
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Groups
Pages
aerospike
as_event.h
Go to the documentation of this file.
1
/*
2
* Copyright 2008-2016 Aerospike, Inc.
3
*
4
* Portions may be licensed to Aerospike, Inc. under one or more contributor
5
* license agreements.
6
*
7
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
8
* use this file except in compliance with the License. You may obtain a copy of
9
* the License at http://www.apache.org/licenses/LICENSE-2.0
10
*
11
* Unless required by applicable law or agreed to in writing, software
12
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
* License for the specific language governing permissions and limitations under
15
* the License.
16
*/
17
#pragma once
18
19
#include <
aerospike/as_queue.h
>
20
#include <pthread.h>
21
#include <stdint.h>
22
#include <stdbool.h>
23
#include <unistd.h>
24
25
/**
26
* @defgroup async_events Asynchronous Event Abstraction
27
*
28
* Generic asynchronous events abstraction. Designed to support multiple event libraries
29
* such as libev and libuv. Only one library can be supported per build.
30
*/
31
#if defined(AS_USE_LIBEV)
32
#include <ev.h>
33
#elif defined(AS_USE_LIBUV)
34
#include <uv.h>
35
#else
36
#endif
37
38
#ifdef __cplusplus
39
extern
"C"
{
40
#endif
41
42
/******************************************************************************
43
* TYPES
44
*****************************************************************************/
45
46
/**
47
* Generic asynchronous event loop abstraction. There is one event loop per thread.
48
* Event loops can be created by the client, or be referenced to externally created event loops.
49
*
50
* @ingroup async_events
51
*/
52
typedef
struct
{
53
#if defined(AS_USE_LIBEV)
54
struct
ev_loop* loop;
55
struct
ev_async wakeup;
56
#elif defined(AS_USE_LIBUV)
57
uv_loop_t* loop;
58
uv_async_t* wakeup;
59
#else
60
void
*
loop
;
61
#endif
62
63
pthread_mutex_t
lock
;
64
as_queue
queue
;
65
pthread_t
thread
;
66
uint32_t
index
;
67
bool
initialized
;
68
}
as_event_loop
;
69
70
/******************************************************************************
71
* GLOBAL VARIABLES
72
*****************************************************************************/
73
74
extern
as_event_loop
*
as_event_loops
;
75
extern
uint32_t
as_event_loop_size
;
76
extern
uint32_t
as_event_loop_current
;
77
78
/******************************************************************************
79
* PUBLIC FUNCTIONS
80
*****************************************************************************/
81
82
/**
83
* Create new event loops. This method should only be called when asynchronous client commands
84
* will be used and the calling program itself is not asynchronous. If this method is used,
85
* it must be called before aerospike_connect().
86
*
87
* @param capacity Number of event loops to create.
88
*
89
* @ingroup async_events
90
*/
91
as_event_loop
*
92
as_event_create_loops
(uint32_t capacity);
93
94
/**
95
* Set the number of externally created event loops. This method should be called when the
96
* calling program wants to share event loops with the client. This reduces resource usage and
97
* can increase performance.
98
*
99
* This method is used in conjunction with as_event_set_external_loop() to fully define the
100
* the external loop to the client and obtain a reference the client's event loop abstraction.
101
*
102
* ~~~~~~~~~~{.c}
103
* struct {
104
* pthread_t thread;
105
* struct ev_loop* loop;
106
* as_event_loop* as_loop;
107
* } my_loop;
108
*
109
* static void* my_loop_worker_thread(void* udata) {
110
* struct my_loop* myloop = udata;
111
* myloop->loop = ev_loop_new(EVFLAG_AUTO);
112
* myloop->as_loop = as_event_set_external_loop(myloop->loop);
113
* ev_loop(myloop->loop, 0);
114
* ev_loop_destroy(myloop->loop);
115
* return NULL;
116
* }
117
*
118
* int capacity = 8;
119
* struct my_loop* loops = malloc(sizeof(struct my_loop) * capacity);
120
* as_event_set_external_loop_capacity(capacity);
121
*
122
* for (int i = 0; i < capacity; i++) {
123
* struct my_loop* myloop = &loops[i];
124
* return pthread_create(&myloop->thread, NULL, my_loop_worker_thread, myloop) == 0;
125
* }
126
* ~~~~~~~~~~
127
*
128
* @param capacity Number of externally created event loops.
129
*
130
* @ingroup async_events
131
*/
132
bool
133
as_event_set_external_loop_capacity
(uint32_t capacity);
134
135
/**
136
* Register an external event loop with the client. This method should be called when the
137
* calling program wants to share event loops with the client. This reduces resource usage and
138
* can increase performance.
139
*
140
* This method must be called in the same thread as the event loop that is being registered.
141
*
142
* This method is used in conjunction with as_event_set_external_loop_capacity() to fully define
143
* the external loop to the client and obtain a reference the client's event loop abstraction.
144
*
145
* ~~~~~~~~~~{.c}
146
* struct {
147
* pthread_t thread;
148
* struct ev_loop* loop;
149
* as_event_loop* as_loop;
150
* } my_loop;
151
*
152
* static void* my_loop_worker_thread(void* udata) {
153
* struct my_loop* myloop = udata;
154
* myloop->loop = ev_loop_new(EVFLAG_AUTO);
155
* myloop->as_loop = as_event_set_external_loop(myloop->loop);
156
* ev_loop(myloop->loop, 0);
157
* ev_loop_destroy(myloop->loop);
158
* return NULL;
159
* }
160
*
161
* int capacity = 8;
162
* struct my_loop* loops = malloc(sizeof(struct my_loop) * capacity);
163
* as_event_set_external_loop_capacity(capacity);
164
*
165
* for (int i = 0; i < capacity; i++) {
166
* struct my_loop* myloop = &loops[i];
167
* return pthread_create(&myloop->thread, NULL, my_loop_worker_thread, myloop) == 0;
168
* }
169
* ~~~~~~~~~~
170
*
171
* @param loop External event loop.
172
* @return Client's generic event loop abstraction that is used in client async commands.
173
* Returns NULL if external loop capacity would be exceeded.
174
*
175
* @ingroup async_events
176
*/
177
as_event_loop
*
178
as_event_set_external_loop
(
void
* loop);
179
180
/**
181
* Find client's event loop abstraction given the external event loop.
182
*
183
* @param loop External event loop.
184
* @return Client's generic event loop abstraction that is used in client async commands.
185
* Returns NULL if loop not found.
186
*
187
* @ingroup async_events
188
*/
189
as_event_loop
*
190
as_event_loop_find
(
void
* loop);
191
192
/**
193
* Retrieve a random event loop using round robin distribution.
194
*
195
* @return Client's generic event loop abstraction that is used in client async commands.
196
*
197
* @ingroup async_events
198
*/
199
static
inline
as_event_loop
*
200
as_event_loop_get
()
201
{
202
// Increment is not atomic because it doesn't need to be exactly accurate.
203
uint32_t current = as_event_loop_current++;
204
return
&as_event_loops[current % as_event_loop_size];
205
}
206
207
/**
208
* Close internally created event loops and release memory for event loop abstraction.
209
* This method should be called once on program shutdown if as_event_create_loops() or
210
* as_event_set_external_loop_capacity() was called.
211
*
212
* @ingroup async_events
213
*/
214
void
215
as_event_close_loops
();
216
217
#ifdef __cplusplus
218
}
// end extern "C"
219
#endif