channel.c
Go to the documentation of this file.
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 
24 #include "channel.h"
25 
26 #include <ext/standard/php_var.h>
27 #include <ext/standard/sha1.h>
28 #include <zend_smart_str.h>
29 #include <ext/spl/spl_exceptions.h>
30 #include <zend_exceptions.h>
31 
32 #include <grpc/grpc_security.h>
33 #include <grpc/support/alloc.h>
34 #include <grpc/support/log.h>
35 
36 #include "completion_queue.h"
37 #include "channel_credentials.h"
38 #include "timeval.h"
39 
40 zend_class_entry *grpc_ce_channel;
41 PHP_GRPC_DECLARE_OBJECT_HANDLER(channel_ce_handlers)
45 extern HashTable grpc_persistent_list;
46 extern HashTable grpc_target_upper_bound_map;
47 
49  if (free_channel && channel->wrapped) {
50  grpc_channel_destroy(channel->wrapped);
51  channel->wrapped = NULL;
52  }
53  free(channel->target);
54  free(channel->args_hashstr);
55  free(channel->creds_hashstr);
56  free(channel->key);
57  channel->target = NULL;
58  channel->args_hashstr = NULL;
59  channel->creds_hashstr = NULL;
60  channel->key = NULL;
61 }
62 
65  wrapper->ref_count += 1;
67 }
68 
71  wrapper->ref_count -= 1;
72  if (wrapper->ref_count == 0) {
75  free(wrapper);
76  wrapper = NULL;
77  return;
78  }
80 }
81 
82 /* Frees and destroys an instance of wrapped_grpc_channel */
83 PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_channel)
84  // In_persistent_list is used when the user don't close the channel,
85  // In this case, channels not in the list should be freed.
86  if (p->wrapper != NULL) {
87  php_grpc_channel_unref(p->wrapper);
88  p->wrapper = NULL;
89  }
91 
92 /* Initializes an instance of wrapped_grpc_channel to be associated with an
93  * object of a class specified by class_type */
95  TSRMLS_DC) {
96  PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_channel);
97  zend_object_std_init(&intern->std, class_type TSRMLS_CC);
98  object_properties_init(&intern->std, class_type);
99  PHP_GRPC_FREE_CLASS_OBJECT(wrapped_grpc_channel, channel_ce_handlers);
100 }
101 
102 static bool php_grpc_not_channel_arg_key(const char* key) {
103  static const char* ignoredKeys[] = {
104  "credentials",
105  "force_new",
106  "grpc_target_persist_bound",
107  };
108 
109  for (int i = 0; i < sizeof(ignoredKeys) / sizeof(ignoredKeys[0]); i++) {
110  if (strcmp(key, ignoredKeys[i]) == 0) {
111  return true;
112  }
113  }
114  return false;
115 }
116 
117 int php_grpc_read_args_array(zval *args_array,
118  grpc_channel_args *args TSRMLS_DC) {
119  HashTable *array_hash;
120  int args_index;
121  array_hash = Z_ARRVAL_P(args_array);
122  if (!array_hash) {
123  zend_throw_exception(spl_ce_InvalidArgumentException,
124  "array_hash is NULL", 1 TSRMLS_CC);
125  return FAILURE;
126  }
127 
128  args->args = ecalloc(zend_hash_num_elements(array_hash), sizeof(grpc_arg));
129  args_index = 0;
130 
131  char *key = NULL;
132  zval *data;
133  int key_type;
134 
136  if (key_type != HASH_KEY_IS_STRING) {
137  zend_throw_exception(spl_ce_InvalidArgumentException,
138  "args keys must be strings", 1 TSRMLS_CC);
139  return FAILURE;
140  }
141 
143  continue;
144  }
145 
146  args->args[args_index].key = key;
147  switch (Z_TYPE_P(data)) {
148  case IS_LONG:
149  args->args[args_index].value.integer = (int)Z_LVAL_P(data);
150  args->args[args_index].type = GRPC_ARG_INTEGER;
151  break;
152  case IS_STRING:
153  args->args[args_index].value.string = Z_STRVAL_P(data);
154  args->args[args_index].type = GRPC_ARG_STRING;
155  break;
156  default:
157  zend_throw_exception(spl_ce_InvalidArgumentException,
158  "args values must be int or string", 1 TSRMLS_CC);
159  return FAILURE;
160  }
161  args_index++;
163  args->num_args = args_index;
164  return SUCCESS;
165 }
166 
167 void generate_sha1_str(char *sha1str, char *str, php_grpc_int len) {
168  PHP_SHA1_CTX context;
169  unsigned char digest[20];
170  sha1str[0] = '\0';
171  PHP_SHA1Init(&context);
173  PHP_SHA1Final(digest, &context);
174  make_sha1_digest(sha1str, digest);
175 }
176 
178  char* target,
179  target_bound_le_t* target_bound_status TSRMLS_DC) {
180  zval *data;
183  if (rsrc == NULL) {
184  break;
185  }
186  channel_persistent_le_t* le = rsrc->ptr;
187  // Find the channel sharing the same target.
188  if (strcmp(le->channel->target, target) == 0) {
189  // ref_count=1 means that only the map holds the reference to the channel.
190  if (le->channel->ref_count == 1) {
191  php_grpc_delete_persistent_list_entry(le->channel->key,
192  strlen(le->channel->key)
193  TSRMLS_CC);
194  target_bound_status->current_count -= 1;
195  if (target_bound_status->current_count < target_bound_status->upper_bound) {
196  return true;
197  }
198  }
199  }
201  return false;
202 }
203 
206  target_bound_le_t* target_bound_status;
207  php_grpc_int key_len = strlen(target);
209  key_len, rsrc))) {
210  // Target is not persisted.
211  php_grpc_zend_resource new_rsrc;
212  target_bound_status = malloc(sizeof(target_bound_le_t));
213  if (bound == -1) {
214  // If the bound is not set, use 1 as default.s
215  bound = 1;
216  }
217  target_bound_status->upper_bound = bound;
218  // Init current_count with 1. It should be add 1 when the channel is successfully
219  // created and minus 1 when it is removed from the persistent list.
220  target_bound_status->current_count = 0;
221  new_rsrc.type = le_bound;
222  new_rsrc.ptr = target_bound_status;
225  target, key_len, (void *)&new_rsrc);
227  } else {
228  // The target already in the map recording the upper bound.
229  // If no newer bound set, use the original now.
230  target_bound_status = (target_bound_le_t *)rsrc->ptr;
231  if (bound != -1) {
232  target_bound_status->upper_bound = bound;
233  }
234  }
235  return target_bound_status;
236 }
237 
239  wrapped_grpc_channel *channel,
240  char *target,
242  wrapped_grpc_channel_credentials *creds) {
243  if (creds == NULL) {
245  channel->wrapper->wrapped = grpc_channel_create(target, insecure_creds, &args);
246  grpc_channel_credentials_release(insecure_creds);
247  } else {
248  channel->wrapper->wrapped =
249  grpc_channel_create(target, creds->wrapped, &args);
250  }
251  // There is an Grpc\Channel object refer to it.
252  php_grpc_channel_ref(channel->wrapper);
253  efree(args.args);
254 }
255 
257  wrapped_grpc_channel *channel,
258  char *target,
260  wrapped_grpc_channel_credentials *creds,
261  char *key,
262  php_grpc_int key_len,
263  int target_upper_bound TSRMLS_DC) {
264  target_bound_le_t* target_bound_status =
265  update_and_get_target_upper_bound(target, target_upper_bound);
266  // Check the upper bound status before inserting to the persistent map.
267  if (target_bound_status->current_count >=
268  target_bound_status->upper_bound) {
270  target, target_bound_status TSRMLS_CC)) {
271  // If no channel can be deleted from the persistent map,
272  // do not persist this one.
273  create_channel(channel, target, args, creds);
274  gpr_log(GPR_INFO, "[Warning] The number of channel for the"
275  " target %s is maxed out bounded.\n", target);
276  gpr_log(GPR_INFO, "[Warning] Target upper bound: %d. Current size: %d.\n",
277  target_bound_status->upper_bound,
278  target_bound_status->current_count);
279  gpr_log(GPR_INFO, "[Warning] Target %s will not be persisted.\n", target);
280  return;
281  }
282  }
283  // There is space in the persistent map.
284  php_grpc_zend_resource new_rsrc;
286  // this links each persistent list entry to a destructor
287  new_rsrc.type = le_plink;
288  le = malloc(sizeof(channel_persistent_le_t));
289 
290  create_channel(channel, target, args, creds);
291  target_bound_status->current_count += 1;
292 
293  le->channel = channel->wrapper;
294  new_rsrc.ptr = le;
297  (void *)&new_rsrc);
298  // Persistent map refer to it.
299  php_grpc_channel_ref(channel->wrapper);
301 }
302 
321 PHP_METHOD(Channel, __construct) {
322  wrapped_grpc_channel *channel =
323  PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_channel, getThis());
324  zval *creds_obj = NULL;
325  char *target;
326  php_grpc_int target_length;
327  zval *args_array = NULL;
329  HashTable *array_hash;
330  wrapped_grpc_channel_credentials *creds = NULL;
332  bool force_new = false;
333  zval *force_new_obj = NULL;
334  int target_upper_bound = -1;
335 
336  /* "sa" == 1 string, 1 array */
337  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa", &target,
338  &target_length, &args_array) == FAILURE) {
339  zend_throw_exception(spl_ce_InvalidArgumentException,
340  "Channel expects a string and an array", 1 TSRMLS_CC);
341  return;
342  }
343  array_hash = Z_ARRVAL_P(args_array);
344  if (php_grpc_zend_hash_find(array_hash, "credentials", sizeof("credentials"),
345  (void **)&creds_obj) == SUCCESS) {
346  if (Z_TYPE_P(creds_obj) == IS_NULL) {
347  creds = NULL;
348  } else if (PHP_GRPC_GET_CLASS_ENTRY(creds_obj) !=
350  zend_throw_exception(spl_ce_InvalidArgumentException,
351  "credentials must be a ChannelCredentials object",
352  1 TSRMLS_CC);
353  return;
354  } else {
355  creds = PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_channel_credentials,
356  creds_obj);
357  }
358  }
359  if (php_grpc_zend_hash_find(array_hash, "force_new", sizeof("force_new"),
360  (void **)&force_new_obj) == SUCCESS) {
361  if (PHP_GRPC_BVAL_IS_TRUE(force_new_obj)) {
362  force_new = true;
363  }
364  }
365 
366  if (php_grpc_zend_hash_find(array_hash, "grpc_target_persist_bound",
367  sizeof("grpc_target_persist_bound"),
368  (void **)&force_new_obj) == SUCCESS) {
369  if (Z_TYPE_P(force_new_obj) != IS_LONG) {
370  zend_throw_exception(spl_ce_InvalidArgumentException,
371  "plist_bound must be a number",
372  1 TSRMLS_CC);
373  }
374  target_upper_bound = (int)Z_LVAL_P(force_new_obj);
375  }
376 
377  // parse the rest of the channel args array
378  if (php_grpc_read_args_array(args_array, &args TSRMLS_CC) == FAILURE) {
379  efree(args.args);
380  return;
381  }
382 
383  // Construct a hashkey for the persistent channel
384  // Currently, the hashkey contains 3 parts:
385  // 1. hostname
386  // 2. hash value of the channel args (args_array excluding "credentials",
387  // "force_new" and "grpc_target_persist_bound")
388  // 3. (optional) hash value of the ChannelCredentials object
389 
390  char sha1str[41] = { 0 };
391  unsigned char digest[20] = { 0 };
392  PHP_SHA1_CTX context;
393  PHP_SHA1Init(&context);
394  for (int i = 0; i < args.num_args; i++) {
395  PHP_GRPC_SHA1Update(&context, args.args[i].key, strlen(args.args[i].key) + 1);
396  switch (args.args[i].type) {
397  case GRPC_ARG_INTEGER:
398  PHP_GRPC_SHA1Update(&context, &args.args[i].value.integer, 4);
399  break;
400  case GRPC_ARG_STRING:
401  PHP_GRPC_SHA1Update(&context, args.args[i].value.string, strlen(args.args[i].value.string) + 1);
402  break;
403  default:
404  zend_throw_exception(spl_ce_InvalidArgumentException,
405  "args values must be int or string", 1 TSRMLS_CC);
406  return;
407  }
408  };
409  PHP_SHA1Final(digest, &context);
410  make_sha1_digest(sha1str, digest);
411 
412  php_grpc_int key_len = target_length + strlen(sha1str);
413  if (creds != NULL && creds->hashstr != NULL) {
414  key_len += strlen(creds->hashstr);
415  }
416  char *key = malloc(key_len + 1);
417  strcpy(key, target);
418  strcat(key, sha1str);
419  if (creds != NULL && creds->hashstr != NULL) {
420  strcat(key, creds->hashstr);
421  }
422  channel->wrapper = malloc(sizeof(grpc_channel_wrapper));
423  channel->wrapper->ref_count = 0;
424  channel->wrapper->key = key;
425  channel->wrapper->target = strdup(target);
426  channel->wrapper->args_hashstr = strdup(sha1str);
427  channel->wrapper->creds_hashstr = NULL;
428  channel->wrapper->creds = creds;
429  channel->wrapper->args = args;
430  if (creds != NULL && creds->hashstr != NULL) {
431  php_grpc_int creds_hashstr_len = strlen(creds->hashstr);
432  char *channel_creds_hashstr = malloc(creds_hashstr_len + 1);
433  strcpy(channel_creds_hashstr, creds->hashstr);
434  channel->wrapper->creds_hashstr = channel_creds_hashstr;
435  }
436 
437  gpr_mu_init(&channel->wrapper->mu);
438  if (force_new || (creds != NULL && creds->has_call_creds)) {
439  // If the ChannelCredentials object was composed with a CallCredentials
440  // object, there is no way we can tell them apart. Do NOT persist
441  // them. They should be individually destroyed.
442  create_channel(channel, target, args, creds);
444  key_len, rsrc))) {
446  channel, target, args, creds, key, key_len, target_upper_bound TSRMLS_CC);
447  } else {
448  // Found a previously stored channel in the persistent list
450  if (strcmp(target, le->channel->target) != 0 ||
451  strcmp(sha1str, le->channel->args_hashstr) != 0 ||
452  (creds != NULL && creds->hashstr != NULL &&
453  strcmp(creds->hashstr, le->channel->creds_hashstr) != 0)) {
454  // somehow hash collision
456  channel, target, args, creds, key, key_len, target_upper_bound TSRMLS_CC);
457  } else {
458  efree(args.args);
459  free_grpc_channel_wrapper(channel->wrapper, false);
460  gpr_mu_destroy(&channel->wrapper->mu);
461  free(channel->wrapper);
462  channel->wrapper = NULL;
463  channel->wrapper = le->channel;
464  // One more Grpc\Channel object refer to it.
465  php_grpc_channel_ref(channel->wrapper);
466  update_and_get_target_upper_bound(target, target_upper_bound);
467  }
468  }
469 }
470 
475 PHP_METHOD(Channel, getTarget) {
476  wrapped_grpc_channel *channel =
477  PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_channel, getThis());
478  if (channel->wrapper == NULL) {
479  zend_throw_exception(spl_ce_RuntimeException,
480  "getTarget error."
481  "Channel is already closed.", 1 TSRMLS_CC);
482  return;
483  }
484  gpr_mu_lock(&channel->wrapper->mu);
485  char *target = grpc_channel_get_target(channel->wrapper->wrapped);
486  gpr_mu_unlock(&channel->wrapper->mu);
488  gpr_free(target);
489 }
490 
496 PHP_METHOD(Channel, getConnectivityState) {
497  wrapped_grpc_channel *channel =
498  PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_channel, getThis());
499  if (channel->wrapper == NULL) {
500  zend_throw_exception(spl_ce_RuntimeException,
501  "getConnectivityState error."
502  "Channel is already closed.", 1 TSRMLS_CC);
503  return;
504  }
505  gpr_mu_lock(&channel->wrapper->mu);
506  bool try_to_connect = false;
507  /* "|b" == 1 optional bool */
508  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &try_to_connect)
509  == FAILURE) {
510  zend_throw_exception(spl_ce_InvalidArgumentException,
511  "getConnectivityState expects a bool", 1 TSRMLS_CC);
512  gpr_mu_unlock(&channel->wrapper->mu);
513  return;
514  }
515  int state = grpc_channel_check_connectivity_state(channel->wrapper->wrapped,
516  (int)try_to_connect);
517  gpr_mu_unlock(&channel->wrapper->mu);
518  RETURN_LONG(state);
519 }
520 
528 PHP_METHOD(Channel, watchConnectivityState) {
529  wrapped_grpc_channel *channel =
530  PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_channel, getThis());
531  if (channel->wrapper == NULL) {
532  zend_throw_exception(spl_ce_RuntimeException,
533  "watchConnectivityState error"
534  "Channel is already closed.", 1 TSRMLS_CC);
535  return;
536  }
537  gpr_mu_lock(&channel->wrapper->mu);
538  php_grpc_long last_state;
539  zval *deadline_obj;
540 
541  /* "lO" == 1 long 1 object */
542  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lO",
543  &last_state, &deadline_obj,
544  grpc_ce_timeval) == FAILURE) {
545  zend_throw_exception(spl_ce_InvalidArgumentException,
546  "watchConnectivityState expects 1 long 1 timeval",
547  1 TSRMLS_CC);
548  gpr_mu_unlock(&channel->wrapper->mu);
549  return;
550  }
551 
552  wrapped_grpc_timeval *deadline =
553  PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_timeval, deadline_obj);
555  (grpc_connectivity_state)last_state,
556  deadline->wrapped, completion_queue,
557  NULL);
558  grpc_event event =
561  gpr_mu_unlock(&channel->wrapper->mu);
562  RETURN_BOOL(event.success);
563 }
564 
570  wrapped_grpc_channel *channel =
571  PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_channel, getThis());
572  if (channel->wrapper != NULL) {
574  channel->wrapper = NULL;
575  }
576 }
577 
578 // Delete an entry from the persistent list
579 // Note: this does not destroy or close the underlying grpc_channel
581  TSRMLS_DC) {
585  key_len, rsrc)) {
587  }
589 }
590 
591 // A destructor associated with each list entry from the persistent list
593  TSRMLS_DC) {
595  if (le == NULL) {
596  return;
597  }
598  if (le->channel != NULL) {
599  php_grpc_channel_unref(le->channel);
600  le->channel = NULL;
601  }
602  free(le);
603  le = NULL;
604 }
605 
606 // A destructor associated with each list entry from the target_bound map
608  TSRMLS_DC) {
609  target_bound_le_t *le = (target_bound_le_t *) rsrc->ptr;
610  if (le == NULL) {
611  return;
612  }
613  free(le);
614  le = NULL;
615 }
616 
617 #ifdef GRPC_PHP_DEBUG
618 
623 PHP_METHOD(Channel, cleanPersistentList) {
624  zend_hash_clean(&grpc_persistent_list);
625  zend_hash_clean(&grpc_target_upper_bound_map);
626 }
627 
628 char *grpc_connectivity_state_name(grpc_connectivity_state state) {
629  switch (state) {
630  case GRPC_CHANNEL_IDLE:
631  return "IDLE";
633  return "CONNECTING";
634  case GRPC_CHANNEL_READY:
635  return "READY";
637  return "TRANSIENT_FAILURE";
639  return "SHUTDOWN";
640  }
641  return "UNKNOWN";
642 }
643 
648 PHP_METHOD(Channel, getChannelInfo) {
649  wrapped_grpc_channel *channel =
650  PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_channel, getThis());
651  array_init(return_value);
652  // Info about the target
653  PHP_GRPC_ADD_STRING_TO_ARRAY(return_value, "target",
654  sizeof("target"), channel->wrapper->target, true);
655  // Info about the upper bound for the target
656  target_bound_le_t* target_bound_status =
657  update_and_get_target_upper_bound(channel->wrapper->target, -1);
658  PHP_GRPC_ADD_LONG_TO_ARRAY(return_value, "target_upper_bound",
659  sizeof("target_upper_bound"), target_bound_status->upper_bound);
660  PHP_GRPC_ADD_LONG_TO_ARRAY(return_value, "target_current_size",
661  sizeof("target_current_size"), target_bound_status->current_count);
662  // Info about key
663  PHP_GRPC_ADD_STRING_TO_ARRAY(return_value, "key",
664  sizeof("key"), channel->wrapper->key, true);
665  // Info about persistent channel ref_count
666  PHP_GRPC_ADD_LONG_TO_ARRAY(return_value, "ref_count",
667  sizeof("ref_count"), channel->wrapper->ref_count);
668  // Info about connectivity status
669  int state =
670  grpc_channel_check_connectivity_state(channel->wrapper->wrapped, (int)0);
671  // It should be set to 'true' in PHP 5.6.33
672  PHP_GRPC_ADD_LONG_TO_ARRAY(return_value, "connectivity_status",
673  sizeof("connectivity_status"), state);
674  PHP_GRPC_ADD_STRING_TO_ARRAY(return_value, "ob",
675  sizeof("ob"),
676  grpc_connectivity_state_name(state), true);
677  // Info about the channel is closed or not
678  PHP_GRPC_ADD_BOOL_TO_ARRAY(return_value, "is_valid",
679  sizeof("is_valid"), (channel->wrapper == NULL));
680 }
681 
686 PHP_METHOD(Channel, getPersistentList) {
687  array_init(return_value);
688  zval *data;
690  php_grpc_zend_resource *rsrc =
692  if (rsrc == NULL) {
693  break;
694  }
695  channel_persistent_le_t* le = rsrc->ptr;
696  zval* ret_arr;
697  PHP_GRPC_MAKE_STD_ZVAL(ret_arr);
698  array_init(ret_arr);
699  // Info about the target
700  PHP_GRPC_ADD_STRING_TO_ARRAY(ret_arr, "target",
701  sizeof("target"), le->channel->target, true);
702  // Info about the upper bound for the target
703  target_bound_le_t* target_bound_status =
704  update_and_get_target_upper_bound(le->channel->target, -1);
705  PHP_GRPC_ADD_LONG_TO_ARRAY(ret_arr, "target_upper_bound",
706  sizeof("target_upper_bound"), target_bound_status->upper_bound);
707  PHP_GRPC_ADD_LONG_TO_ARRAY(ret_arr, "target_current_size",
708  sizeof("target_current_size"), target_bound_status->current_count);
709  // Info about key
710  PHP_GRPC_ADD_STRING_TO_ARRAY(ret_arr, "key",
711  sizeof("key"), le->channel->key, true);
712  // Info about persistent channel ref_count
713  PHP_GRPC_ADD_LONG_TO_ARRAY(ret_arr, "ref_count",
714  sizeof("ref_count"), le->channel->ref_count);
715  // Info about connectivity status
716  int state =
717  grpc_channel_check_connectivity_state(le->channel->wrapped, (int)0);
718  // It should be set to 'true' in PHP 5.6.33
719  PHP_GRPC_ADD_LONG_TO_ARRAY(ret_arr, "connectivity_status",
720  sizeof("connectivity_status"), state);
721  PHP_GRPC_ADD_STRING_TO_ARRAY(ret_arr, "ob",
722  sizeof("ob"),
723  grpc_connectivity_state_name(state), true);
724  add_assoc_zval(return_value, le->channel->key, ret_arr);
725  PHP_GRPC_FREE_STD_ZVAL(ret_arr);
727 }
728 #endif
729 
730 
731 ZEND_BEGIN_ARG_INFO_EX(arginfo_construct, 0, 0, 2)
732  ZEND_ARG_INFO(0, target)
733  ZEND_ARG_INFO(0, args)
734 ZEND_END_ARG_INFO()
735 
736 ZEND_BEGIN_ARG_INFO_EX(arginfo_getTarget, 0, 0, 0)
737 ZEND_END_ARG_INFO()
738 
739 ZEND_BEGIN_ARG_INFO_EX(arginfo_getConnectivityState, 0, 0, 0)
740  ZEND_ARG_INFO(0, try_to_connect)
741 ZEND_END_ARG_INFO()
742 
743 ZEND_BEGIN_ARG_INFO_EX(arginfo_watchConnectivityState, 0, 0, 2)
744  ZEND_ARG_INFO(0, last_state)
745  ZEND_ARG_INFO(0, deadline)
746 ZEND_END_ARG_INFO()
747 
748 ZEND_BEGIN_ARG_INFO_EX(arginfo_close, 0, 0, 0)
749 ZEND_END_ARG_INFO()
750 
751 #ifdef GRPC_PHP_DEBUG
752 ZEND_BEGIN_ARG_INFO_EX(arginfo_getChannelInfo, 0, 0, 0)
753 ZEND_END_ARG_INFO()
754 
755 ZEND_BEGIN_ARG_INFO_EX(arginfo_cleanPersistentList, 0, 0, 0)
756 ZEND_END_ARG_INFO()
757 
758 ZEND_BEGIN_ARG_INFO_EX(arginfo_getPersistentList, 0, 0, 0)
759 ZEND_END_ARG_INFO()
760 #endif
761 
762 
763 static zend_function_entry channel_methods[] = {
764  PHP_ME(Channel, __construct, arginfo_construct,
765  ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
766  PHP_ME(Channel, getTarget, arginfo_getTarget,
767  ZEND_ACC_PUBLIC)
768  PHP_ME(Channel, getConnectivityState, arginfo_getConnectivityState,
769  ZEND_ACC_PUBLIC)
770  PHP_ME(Channel, watchConnectivityState, arginfo_watchConnectivityState,
771  ZEND_ACC_PUBLIC)
772  PHP_ME(Channel, close, arginfo_close,
773  ZEND_ACC_PUBLIC)
774  #ifdef GRPC_PHP_DEBUG
775  PHP_ME(Channel, getChannelInfo, arginfo_getChannelInfo,
776  ZEND_ACC_PUBLIC)
777  PHP_ME(Channel, cleanPersistentList, arginfo_cleanPersistentList,
778  ZEND_ACC_PUBLIC)
779  PHP_ME(Channel, getPersistentList, arginfo_getPersistentList,
780  ZEND_ACC_PUBLIC)
781  #endif
782  PHP_FE_END
783 };
784 
786  zend_class_entry ce;
787  INIT_CLASS_ENTRY(ce, "Grpc\\Channel", channel_methods);
788  ce.create_object = create_wrapped_grpc_channel;
789  grpc_ce_channel = zend_register_internal_class(&ce TSRMLS_CC);
791  le_plink = zend_register_list_destructors_ex(
792  NULL, php_grpc_channel_plink_dtor, "Persistent Channel", module_number);
793  ZEND_HASH_INIT(&grpc_persistent_list, 20, EG(persistent_list).pDestructor, 1);
794  // Register the target->upper_bound map.
795  le_bound = zend_register_list_destructors_ex(
796  NULL, php_grpc_target_bound_dtor, "Target Bound", module_number);
797  ZEND_HASH_INIT(&grpc_target_upper_bound_map, 20, EG(persistent_list).pDestructor, 1);
798 
799  PHP_GRPC_INIT_HANDLER(wrapped_grpc_channel, channel_ce_handlers);
800  return SUCCESS;
801 }
php_grpc_persistent_list_delete_unused_channel
bool php_grpc_persistent_list_delete_unused_channel(char *target, target_bound_le_t *target_bound_status TSRMLS_DC)
Definition: channel.c:177
grpc_arg
Definition: grpc_types.h:103
xds_interop_client.str
str
Definition: xds_interop_client.py:487
php_grpc_not_channel_arg_key
static bool php_grpc_not_channel_arg_key(const char *key)
Definition: channel.c:102
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
php_grpc_channel_plink_dtor
static void php_grpc_channel_plink_dtor(php_grpc_zend_resource *rsrc TSRMLS_DC)
Definition: channel.c:592
GRPC_CHANNEL_READY
@ GRPC_CHANNEL_READY
Definition: include/grpc/impl/codegen/connectivity_state.h:36
gpr_mu_unlock
GPRAPI void gpr_mu_unlock(gpr_mu *mu)
completion_queue
grpc_completion_queue * completion_queue
Definition: completion_queue.c:21
log.h
GRPC_ARG_INTEGER
@ GRPC_ARG_INTEGER
Definition: grpc_types.h:81
grpc_ce_channel_credentials
zend_class_entry * grpc_ce_channel_credentials
Definition: channel_credentials.c:36
php_grpc_zend_object
#define php_grpc_zend_object
Definition: php7_wrapper.h:27
php_grpc_long
#define php_grpc_long
Definition: php7_wrapper.h:25
PHP_GRPC_FREE_STD_ZVAL
#define PHP_GRPC_FREE_STD_ZVAL(pzv)
Definition: php7_wrapper.h:44
global_persistent_list_mu
static gpr_mu global_persistent_list_mu
Definition: channel.c:42
GRPC_ARG_STRING
@ GRPC_ARG_STRING
Definition: grpc_types.h:80
channel_credentials.h
PHP_GRPC_HASH_FOREACH_VAL_START
#define PHP_GRPC_HASH_FOREACH_VAL_START(ht, data)
Definition: php7_wrapper.h:86
channel_methods
static zend_function_entry channel_methods[]
Definition: channel.c:763
create_and_add_channel_to_persistent_list
void create_and_add_channel_to_persistent_list(wrapped_grpc_channel *channel, char *target, grpc_channel_args args, wrapped_grpc_channel_credentials *creds, char *key, php_grpc_int key_len, int target_upper_bound TSRMLS_DC)
Definition: channel.c:256
channel.h
grpc_channel_check_connectivity_state
GRPCAPI grpc_connectivity_state grpc_channel_check_connectivity_state(grpc_channel *channel, int try_to_connect)
Definition: channel_connectivity.cc:56
_grpc_channel_wrapper::mu
gpr_mu mu
Definition: src/php/ext/grpc/channel.h:41
gpr_free
GPRAPI void gpr_free(void *ptr)
Definition: alloc.cc:51
GRPC_CHANNEL_TRANSIENT_FAILURE
@ GRPC_CHANNEL_TRANSIENT_FAILURE
Definition: include/grpc/impl/codegen/connectivity_state.h:38
grpc_persistent_list
HashTable grpc_persistent_list
Definition: php_grpc.c:45
grpc_channel_get_target
GRPCAPI char * grpc_channel_get_target(grpc_channel *channel)
Definition: channel.cc:256
PHP_GRPC_PERSISTENT_LIST_UPDATE
#define PHP_GRPC_PERSISTENT_LIST_UPDATE(plist, key, len, rsrc)
Definition: php7_wrapper.h:132
GRPC_STARTUP_FUNCTION
GRPC_STARTUP_FUNCTION(channel)
Definition: channel.c:785
gpr_inf_future
GPRAPI gpr_timespec gpr_inf_future(gpr_clock_type type)
Definition: src/core/lib/gpr/time.cc:55
_target_bound_le::current_count
int current_count
Definition: src/php/ext/grpc/channel.h:75
xds_manager.p
p
Definition: xds_manager.py:60
grpc_security.h
grpc_channel_args
Definition: grpc_types.h:132
PHP_GRPC_INIT_HANDLER
#define PHP_GRPC_INIT_HANDLER(class_object, handler_name)
Definition: php7_wrapper.h:140
create_channel
void create_channel(wrapped_grpc_channel *channel, char *target, grpc_channel_args args, wrapped_grpc_channel_credentials *creds)
Definition: channel.c:238
PHP_GRPC_ADD_LONG_TO_ARRAY
#define PHP_GRPC_ADD_LONG_TO_ARRAY(val, key, key_len, str)
Definition: php7_wrapper.h:48
grpc_connectivity_state
grpc_connectivity_state
Definition: include/grpc/impl/codegen/connectivity_state.h:30
PHP_GRPC_FREE_WRAPPED_FUNC_END
#define PHP_GRPC_FREE_WRAPPED_FUNC_END()
Definition: php7_wrapper.h:73
gpr_mu_destroy
GPRAPI void gpr_mu_destroy(gpr_mu *mu)
php_grpc_read_args_array
int php_grpc_read_args_array(zval *args_array, grpc_channel_args *args TSRMLS_DC)
Definition: channel.c:117
framework.rpc.grpc_channelz.Channel
Channel
Definition: grpc_channelz.py:32
if
if(p->wrapper !=NULL)
Definition: channel.c:86
channel
wrapped_grpc_channel * channel
Definition: src/php/ext/grpc/call.h:33
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
generate_sha1_str
void generate_sha1_str(char *sha1str, char *str, php_grpc_int len)
Definition: channel.c:167
xds_interop_client.int
int
Definition: xds_interop_client.py:113
PHP_GRPC_DECLARE_OBJECT_HANDLER
#define PHP_GRPC_DECLARE_OBJECT_HANDLER(handler_name)
Definition: php7_wrapper.h:146
php_grpc_zend_hash_del
static int php_grpc_zend_hash_del(HashTable *ht, char *key, int len)
Definition: php7_wrapper.h:118
PHP_GRPC_GET_WRAPPED_OBJECT
#define PHP_GRPC_GET_WRAPPED_OBJECT(class_object, zv)
Definition: php7_wrapper.h:149
php_grpc_int
#define php_grpc_int
Definition: php7_wrapper.h:24
PHP_METHOD
PHP_METHOD(Channel, __construct)
Definition: channel.c:321
PHP_GRPC_ADD_STRING_TO_ARRAY
#define PHP_GRPC_ADD_STRING_TO_ARRAY(val, key, key_len, str, dup)
Definition: php7_wrapper.h:46
completion_queue.h
le_bound
int le_bound
Definition: channel.c:44
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
gpr_mu_init
GPRAPI void gpr_mu_init(gpr_mu *mu)
grpc_event
Definition: grpc_types.h:564
PHP_GRPC_HASH_FOREACH_STR_KEY_VAL_START
#define PHP_GRPC_HASH_FOREACH_STR_KEY_VAL_START(ht, key, key_type, data)
Definition: php7_wrapper.h:89
grpc_insecure_credentials_create
GRPCAPI grpc_channel_credentials * grpc_insecure_credentials_create()
Definition: core/lib/security/credentials/insecure/insecure_credentials.cc:64
GRPC_CHANNEL_IDLE
@ GRPC_CHANNEL_IDLE
Definition: include/grpc/impl/codegen/connectivity_state.h:32
free_channel
static void free_channel(void *arg, grpc_error_handle)
Definition: channel_stack_test.cc:68
_channel_persistent_le
Definition: src/php/ext/grpc/channel.h:69
close
#define close
Definition: test-fs.c:48
PHP_GRPC_RETVAL_STRING
#define PHP_GRPC_RETVAL_STRING(val, dup)
Definition: php7_wrapper.h:40
gpr_mu_lock
GPRAPI void gpr_mu_lock(gpr_mu *mu)
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
wrapper
grpc_channel_wrapper * wrapper
Definition: src/php/ext/grpc/channel.h:48
timeval.h
update_and_get_target_upper_bound
target_bound_le_t * update_and_get_target_upper_bound(char *target, int bound)
Definition: channel.c:204
GRPC_CHANNEL_CONNECTING
@ GRPC_CHANNEL_CONNECTING
Definition: include/grpc/impl/codegen/connectivity_state.h:34
grpc::testing::SUCCESS
@ SUCCESS
Definition: h2_ssl_cert_test.cc:201
grpc_channel_credentials_release
GRPCAPI void grpc_channel_credentials_release(grpc_channel_credentials *creds)
Definition: credentials.cc:36
le_plink
int le_plink
Definition: channel.c:43
grpc_completion_queue_pluck
GRPCAPI grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cq, void *tag, gpr_timespec deadline, void *reserved)
Definition: completion_queue.cc:1328
grpc_channel_create
GRPCAPI grpc_channel * grpc_channel_create(const char *target, grpc_channel_credentials *creds, const grpc_channel_args *args)
Definition: chttp2_connector.cc:366
_grpc_channel_wrapper::ref_count
size_t ref_count
Definition: src/php/ext/grpc/channel.h:40
PHP_GRPC_BVAL_IS_TRUE
#define PHP_GRPC_BVAL_IS_TRUE(zv)
Definition: php7_wrapper.h:123
key
const char * key
Definition: hpack_parser_table.cc:164
PHP_GRPC_HASH_FOREACH_END
#define PHP_GRPC_HASH_FOREACH_END()
Definition: php7_wrapper.h:105
gpr_mu
pthread_mutex_t gpr_mu
Definition: impl/codegen/sync_posix.h:47
PHP_GRPC_PERSISTENT_LIST_FIND
#define PHP_GRPC_PERSISTENT_LIST_FIND(plist, key, len, rsrc)
Definition: php7_wrapper.h:130
intern
upb_strtable_uninit & intern
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/map.c:222
PHP_GRPC_GET_CLASS_ENTRY
#define PHP_GRPC_GET_CLASS_ENTRY(object)
Definition: php7_wrapper.h:138
PHP_GRPC_MAKE_STD_ZVAL
#define PHP_GRPC_MAKE_STD_ZVAL(pzv)
Definition: php7_wrapper.h:42
grpc_target_upper_bound_map
HashTable grpc_target_upper_bound_map
Definition: php_grpc.c:46
PHP_GRPC_ALLOC_CLASS_OBJECT
#define PHP_GRPC_ALLOC_CLASS_OBJECT(class_object)
Definition: php7_wrapper.h:77
alloc.h
_grpc_channel_wrapper
Definition: src/php/ext/grpc/channel.h:34
PHP_GRPC_SHA1Update
#define PHP_GRPC_SHA1Update(cxt, str, len)
Definition: php7_wrapper.h:128
grpc_channel_destroy
GRPCAPI void grpc_channel_destroy(grpc_channel *channel)
Definition: channel.cc:437
state
Definition: bloaty/third_party/zlib/contrib/blast/blast.c:41
_target_bound_le::upper_bound
int upper_bound
Definition: src/php/ext/grpc/channel.h:74
php_grpc_target_bound_dtor
static void php_grpc_target_bound_dtor(php_grpc_zend_resource *rsrc TSRMLS_DC)
Definition: channel.c:607
php_grpc_zend_resource
#define php_grpc_zend_resource
Definition: php7_wrapper.h:121
PHP_GRPC_FREE_CLASS_OBJECT
#define PHP_GRPC_FREE_CLASS_OBJECT(class_object, handler)
Definition: php7_wrapper.h:82
PHP_GRPC_HASH_VALPTR_TO_VAL
#define PHP_GRPC_HASH_VALPTR_TO_VAL(data)
Definition: php7_wrapper.h:95
grpc_channel_watch_connectivity_state
GRPCAPI void grpc_channel_watch_connectivity_state(grpc_channel *channel, grpc_connectivity_state last_observed_state, gpr_timespec deadline, grpc_completion_queue *cq, void *tag)
Definition: channel_connectivity.cc:227
php_grpc_channel_unref
void php_grpc_channel_unref(grpc_channel_wrapper *wrapper)
Definition: channel.c:69
grpc_ce_timeval
zend_class_entry * grpc_ce_timeval
Definition: timeval.c:29
free_grpc_channel_wrapper
void free_grpc_channel_wrapper(grpc_channel_wrapper *channel, bool free_channel)
Definition: channel.c:48
context
grpc::ClientContext context
Definition: istio_echo_server_lib.cc:61
GRPC_CHANNEL_SHUTDOWN
@ GRPC_CHANNEL_SHUTDOWN
Definition: include/grpc/impl/codegen/connectivity_state.h:40
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
tests.unit._exit_scenarios.try_to_connect
try_to_connect
Definition: _exit_scenarios.py:189
key_type
upb_fieldtype_t key_type
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1071
PHP_GRPC_ADD_BOOL_TO_ARRAY
#define PHP_GRPC_ADD_BOOL_TO_ARRAY(val, key, key_len, str)
Definition: php7_wrapper.h:50
php_grpc_delete_persistent_list_entry
void php_grpc_delete_persistent_list_entry(char *key, php_grpc_int key_len TSRMLS_DC)
Definition: channel.c:580
GPR_CLOCK_REALTIME
@ GPR_CLOCK_REALTIME
Definition: gpr_types.h:39
create_wrapped_grpc_channel
php_grpc_zend_object create_wrapped_grpc_channel(zend_class_entry *class_type TSRMLS_DC)
Definition: channel.c:94
PHP_GRPC_FREE_WRAPPED_FUNC_START
#define PHP_GRPC_FREE_WRAPPED_FUNC_START(class_object)
Definition: php7_wrapper.h:70
php_grpc_zend_hash_find
static int php_grpc_zend_hash_find(HashTable *ht, char *key, int len, void **value)
Definition: php7_wrapper.h:107
ZEND_HASH_INIT
#define ZEND_HASH_INIT(hash_table, limit, descriptor, zend_bool)
Definition: src/php/ext/grpc/channel.h:28
setup.target
target
Definition: third_party/bloaty/third_party/protobuf/python/setup.py:179
grpc_channel_credentials
Definition: src/core/lib/security/credentials/credentials.h:96
_target_bound_le
Definition: src/php/ext/grpc/channel.h:73
php_grpc_channel_ref
void php_grpc_channel_ref(grpc_channel_wrapper *wrapper)
Definition: channel.c:63
grpc_ce_channel
zend_class_entry * grpc_ce_channel
Definition: channel.c:40
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
strdup
#define strdup(ptr)
Definition: acountry.c:55


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:58:43