1 /*
2 *
3 * Copyright 2015 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * 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,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19 #include "php_grpc.h"
20
21 #include "call.h"
22 #include "channel.h"
23 #include "server.h"
24 #include "timeval.h"
25 #include "channel_credentials.h"
26 #include "call_credentials.h"
27 #include "server_credentials.h"
28 #include "completion_queue.h"
29
30 ZEND_DECLARE_MODULE_GLOBALS(grpc)
31 static PHP_GINIT_FUNCTION(grpc);
32 HashTable grpc_persistent_list;
33 HashTable grpc_target_upper_bound_map;
34 /* {{{ grpc_functions[]
35 *
36 * Every user visible function must have an entry in grpc_functions[].
37 */
38 const zend_function_entry grpc_functions[] = {
39 PHP_FE_END /* Must be the last line in grpc_functions[] */
40 };
41 /* }}} */
42
43 /* {{{ grpc_module_entry
44 */
45 zend_module_entry grpc_module_entry = {
46 STANDARD_MODULE_HEADER,
47 "grpc",
48 grpc_functions,
49 PHP_MINIT(grpc),
50 PHP_MSHUTDOWN(grpc),
51 PHP_RINIT(grpc),
52 NULL,
53 PHP_MINFO(grpc),
54 PHP_GRPC_VERSION,
55 PHP_MODULE_GLOBALS(grpc),
56 PHP_GINIT(grpc),
57 NULL,
58 NULL,
59 STANDARD_MODULE_PROPERTIES_EX};
60 /* }}} */
61
62 #ifdef COMPILE_DL_GRPC
63 ZEND_GET_MODULE(grpc)
64 #endif
65
66 /* {{{ PHP_INI
67 */
68 /* Remove comments and fill if you need to have entries in php.ini
69 PHP_INI_BEGIN()
70 STD_PHP_INI_ENTRY("grpc.global_value", "42", PHP_INI_ALL, OnUpdateLong,
71 global_value, zend_grpc_globals, grpc_globals)
72 STD_PHP_INI_ENTRY("grpc.global_string", "foobar", PHP_INI_ALL,
73 OnUpdateString, global_string, zend_grpc_globals,
74 grpc_globals)
75 PHP_INI_END()
76 */
77 /* }}} */
78
79 /* {{{ php_grpc_init_globals
80 */
81 /* Uncomment this function if you have INI entries
82 static void php_grpc_init_globals(zend_grpc_globals *grpc_globals)
83 {
84 grpc_globals->global_value = 0;
85 grpc_globals->global_string = NULL;
86 }
87 */
88 /* }}} */
89
90 /* {{{ PHP_MINIT_FUNCTION
91 */
PHP_MINIT_FUNCTION(grpc)92 PHP_MINIT_FUNCTION(grpc) {
93 /* If you have INI entries, uncomment these lines
94 REGISTER_INI_ENTRIES();
95 */
96 /* Register call error constants */
97 REGISTER_LONG_CONSTANT("Grpc\\CALL_OK", GRPC_CALL_OK,
98 CONST_CS | CONST_PERSISTENT);
99 REGISTER_LONG_CONSTANT("Grpc\\CALL_ERROR", GRPC_CALL_ERROR,
100 CONST_CS | CONST_PERSISTENT);
101 REGISTER_LONG_CONSTANT("Grpc\\CALL_ERROR_NOT_ON_SERVER",
102 GRPC_CALL_ERROR_NOT_ON_SERVER,
103 CONST_CS | CONST_PERSISTENT);
104 REGISTER_LONG_CONSTANT("Grpc\\CALL_ERROR_NOT_ON_CLIENT",
105 GRPC_CALL_ERROR_NOT_ON_CLIENT,
106 CONST_CS | CONST_PERSISTENT);
107 REGISTER_LONG_CONSTANT("Grpc\\CALL_ERROR_ALREADY_INVOKED",
108 GRPC_CALL_ERROR_ALREADY_INVOKED,
109 CONST_CS | CONST_PERSISTENT);
110 REGISTER_LONG_CONSTANT("Grpc\\CALL_ERROR_NOT_INVOKED",
111 GRPC_CALL_ERROR_NOT_INVOKED,
112 CONST_CS | CONST_PERSISTENT);
113 REGISTER_LONG_CONSTANT("Grpc\\CALL_ERROR_ALREADY_FINISHED",
114 GRPC_CALL_ERROR_ALREADY_FINISHED,
115 CONST_CS | CONST_PERSISTENT);
116 REGISTER_LONG_CONSTANT("Grpc\\CALL_ERROR_TOO_MANY_OPERATIONS",
117 GRPC_CALL_ERROR_TOO_MANY_OPERATIONS,
118 CONST_CS | CONST_PERSISTENT);
119 REGISTER_LONG_CONSTANT("Grpc\\CALL_ERROR_INVALID_FLAGS",
120 GRPC_CALL_ERROR_INVALID_FLAGS,
121 CONST_CS | CONST_PERSISTENT);
122
123 /* Register flag constants */
124 REGISTER_LONG_CONSTANT("Grpc\\WRITE_BUFFER_HINT", GRPC_WRITE_BUFFER_HINT,
125 CONST_CS | CONST_PERSISTENT);
126 REGISTER_LONG_CONSTANT("Grpc\\WRITE_NO_COMPRESS", GRPC_WRITE_NO_COMPRESS,
127 CONST_CS | CONST_PERSISTENT);
128
129 /* Register status constants */
130 REGISTER_LONG_CONSTANT("Grpc\\STATUS_OK", GRPC_STATUS_OK,
131 CONST_CS | CONST_PERSISTENT);
132 REGISTER_LONG_CONSTANT("Grpc\\STATUS_CANCELLED", GRPC_STATUS_CANCELLED,
133 CONST_CS | CONST_PERSISTENT);
134 REGISTER_LONG_CONSTANT("Grpc\\STATUS_UNKNOWN", GRPC_STATUS_UNKNOWN,
135 CONST_CS | CONST_PERSISTENT);
136 REGISTER_LONG_CONSTANT("Grpc\\STATUS_INVALID_ARGUMENT",
137 GRPC_STATUS_INVALID_ARGUMENT,
138 CONST_CS | CONST_PERSISTENT);
139 REGISTER_LONG_CONSTANT("Grpc\\STATUS_DEADLINE_EXCEEDED",
140 GRPC_STATUS_DEADLINE_EXCEEDED,
141 CONST_CS | CONST_PERSISTENT);
142 REGISTER_LONG_CONSTANT("Grpc\\STATUS_NOT_FOUND", GRPC_STATUS_NOT_FOUND,
143 CONST_CS | CONST_PERSISTENT);
144 REGISTER_LONG_CONSTANT("Grpc\\STATUS_ALREADY_EXISTS",
145 GRPC_STATUS_ALREADY_EXISTS,
146 CONST_CS | CONST_PERSISTENT);
147 REGISTER_LONG_CONSTANT("Grpc\\STATUS_PERMISSION_DENIED",
148 GRPC_STATUS_PERMISSION_DENIED,
149 CONST_CS | CONST_PERSISTENT);
150 REGISTER_LONG_CONSTANT("Grpc\\STATUS_UNAUTHENTICATED",
151 GRPC_STATUS_UNAUTHENTICATED,
152 CONST_CS | CONST_PERSISTENT);
153 REGISTER_LONG_CONSTANT("Grpc\\STATUS_RESOURCE_EXHAUSTED",
154 GRPC_STATUS_RESOURCE_EXHAUSTED,
155 CONST_CS | CONST_PERSISTENT);
156 REGISTER_LONG_CONSTANT("Grpc\\STATUS_FAILED_PRECONDITION",
157 GRPC_STATUS_FAILED_PRECONDITION,
158 CONST_CS | CONST_PERSISTENT);
159 REGISTER_LONG_CONSTANT("Grpc\\STATUS_ABORTED", GRPC_STATUS_ABORTED,
160 CONST_CS | CONST_PERSISTENT);
161 REGISTER_LONG_CONSTANT("Grpc\\STATUS_OUT_OF_RANGE",
162 GRPC_STATUS_OUT_OF_RANGE,
163 CONST_CS | CONST_PERSISTENT);
164 REGISTER_LONG_CONSTANT("Grpc\\STATUS_UNIMPLEMENTED",
165 GRPC_STATUS_UNIMPLEMENTED,
166 CONST_CS | CONST_PERSISTENT);
167 REGISTER_LONG_CONSTANT("Grpc\\STATUS_INTERNAL", GRPC_STATUS_INTERNAL,
168 CONST_CS | CONST_PERSISTENT);
169 REGISTER_LONG_CONSTANT("Grpc\\STATUS_UNAVAILABLE", GRPC_STATUS_UNAVAILABLE,
170 CONST_CS | CONST_PERSISTENT);
171 REGISTER_LONG_CONSTANT("Grpc\\STATUS_DATA_LOSS", GRPC_STATUS_DATA_LOSS,
172 CONST_CS | CONST_PERSISTENT);
173
174 /* Register op type constants */
175 REGISTER_LONG_CONSTANT("Grpc\\OP_SEND_INITIAL_METADATA",
176 GRPC_OP_SEND_INITIAL_METADATA,
177 CONST_CS | CONST_PERSISTENT);
178 REGISTER_LONG_CONSTANT("Grpc\\OP_SEND_MESSAGE",
179 GRPC_OP_SEND_MESSAGE,
180 CONST_CS | CONST_PERSISTENT);
181 REGISTER_LONG_CONSTANT("Grpc\\OP_SEND_CLOSE_FROM_CLIENT",
182 GRPC_OP_SEND_CLOSE_FROM_CLIENT,
183 CONST_CS | CONST_PERSISTENT);
184 REGISTER_LONG_CONSTANT("Grpc\\OP_SEND_STATUS_FROM_SERVER",
185 GRPC_OP_SEND_STATUS_FROM_SERVER,
186 CONST_CS | CONST_PERSISTENT);
187 REGISTER_LONG_CONSTANT("Grpc\\OP_RECV_INITIAL_METADATA",
188 GRPC_OP_RECV_INITIAL_METADATA,
189 CONST_CS | CONST_PERSISTENT);
190 REGISTER_LONG_CONSTANT("Grpc\\OP_RECV_MESSAGE",
191 GRPC_OP_RECV_MESSAGE,
192 CONST_CS | CONST_PERSISTENT);
193 REGISTER_LONG_CONSTANT("Grpc\\OP_RECV_STATUS_ON_CLIENT",
194 GRPC_OP_RECV_STATUS_ON_CLIENT,
195 CONST_CS | CONST_PERSISTENT);
196 REGISTER_LONG_CONSTANT("Grpc\\OP_RECV_CLOSE_ON_SERVER",
197 GRPC_OP_RECV_CLOSE_ON_SERVER,
198 CONST_CS | CONST_PERSISTENT);
199
200 /* Register connectivity state constants */
201 REGISTER_LONG_CONSTANT("Grpc\\CHANNEL_IDLE",
202 GRPC_CHANNEL_IDLE,
203 CONST_CS | CONST_PERSISTENT);
204 REGISTER_LONG_CONSTANT("Grpc\\CHANNEL_CONNECTING",
205 GRPC_CHANNEL_CONNECTING,
206 CONST_CS | CONST_PERSISTENT);
207 REGISTER_LONG_CONSTANT("Grpc\\CHANNEL_READY",
208 GRPC_CHANNEL_READY,
209 CONST_CS | CONST_PERSISTENT);
210 REGISTER_LONG_CONSTANT("Grpc\\CHANNEL_TRANSIENT_FAILURE",
211 GRPC_CHANNEL_TRANSIENT_FAILURE,
212 CONST_CS | CONST_PERSISTENT);
213 REGISTER_LONG_CONSTANT("Grpc\\CHANNEL_FATAL_FAILURE",
214 GRPC_CHANNEL_SHUTDOWN,
215 CONST_CS | CONST_PERSISTENT);
216
217 grpc_init_call(TSRMLS_C);
218 GRPC_STARTUP(channel);
219 grpc_init_server(TSRMLS_C);
220 grpc_init_timeval(TSRMLS_C);
221 grpc_init_channel_credentials(TSRMLS_C);
222 grpc_init_call_credentials(TSRMLS_C);
223 grpc_init_server_credentials(TSRMLS_C);
224 return SUCCESS;
225 }
226 /* }}} */
227
228 /* {{{ PHP_MSHUTDOWN_FUNCTION
229 */
PHP_MSHUTDOWN_FUNCTION(grpc)230 PHP_MSHUTDOWN_FUNCTION(grpc) {
231 /* uncomment this line if you have INI entries
232 UNREGISTER_INI_ENTRIES();
233 */
234 // WARNING: This function IS being called by PHP when the extension
235 // is unloaded but the logs were somehow suppressed.
236 if (GRPC_G(initialized)) {
237 zend_hash_clean(&grpc_persistent_list);
238 zend_hash_destroy(&grpc_persistent_list);
239 zend_hash_clean(&grpc_target_upper_bound_map);
240 zend_hash_destroy(&grpc_target_upper_bound_map);
241 grpc_shutdown_timeval(TSRMLS_C);
242 grpc_php_shutdown_completion_queue(TSRMLS_C);
243 grpc_shutdown();
244 GRPC_G(initialized) = 0;
245 }
246 return SUCCESS;
247 }
248 /* }}} */
249
250 /* {{{ PHP_MINFO_FUNCTION
251 */
PHP_MINFO_FUNCTION(grpc)252 PHP_MINFO_FUNCTION(grpc) {
253 php_info_print_table_start();
254 php_info_print_table_row(2, "grpc support", "enabled");
255 php_info_print_table_row(2, "grpc module version", PHP_GRPC_VERSION);
256 php_info_print_table_end();
257 /* Remove comments if you have entries in php.ini
258 DISPLAY_INI_ENTRIES();
259 */
260 }
261 /* }}} */
262
263 /* {{{ PHP_RINIT_FUNCTION
264 */
PHP_RINIT_FUNCTION(grpc)265 PHP_RINIT_FUNCTION(grpc) {
266 if (!GRPC_G(initialized)) {
267 grpc_init();
268 grpc_php_init_completion_queue(TSRMLS_C);
269 GRPC_G(initialized) = 1;
270 }
271 return SUCCESS;
272 }
273 /* }}} */
274
275 /* {{{ PHP_GINIT_FUNCTION
276 */
PHP_GINIT_FUNCTION(grpc)277 static PHP_GINIT_FUNCTION(grpc) {
278 grpc_globals->initialized = 0;
279 }
280 /* }}} */
281
282 /* The previous line is meant for vim and emacs, so it can correctly fold and
283 unfold functions in source code. See the corresponding marks just before
284 function definition, where the functions purpose is also documented. Please
285 follow this convention for the convenience of others editing your code.
286 */
287