PHP_METHOD(air_mysql_waiter, step_2) { AIR_INIT_THIS; zval *services = zend_read_property(Z_OBJCE_P(self), self, ZEND_STRL("_services"), 0 TSRMLS_CC); zval *responses = zend_read_property(Z_OBJCE_P(self), self, ZEND_STRL("_responses"), 0 TSRMLS_CC); zval *context = zend_read_property(Z_OBJCE_P(self), self, ZEND_STRL("_context"), 0 TSRMLS_CC); zval *m2s = air_arr_find(context, ZEND_STRS("m2s")); zval *reads = air_arr_find(context, ZEND_STRS("reads")); zval *waited = air_arr_find(context, ZEND_STRS("waited")); zval *processed = air_arr_find(context, ZEND_STRS("processed")); zval *step = air_arr_find(context, ZEND_STRS("step")); zend_class_entry *mysqli_ce = air_get_ce(ZEND_STRL("mysqli") TSRMLS_CC); ulong idx; char *key; int key_len; zval *mysqli; AIR_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(reads), idx, key, key_len, mysqli){ zval *service_id = air_arr_idx_find(m2s, air_mysqli_get_id(mysqli TSRMLS_CC)); zval *service = air_arr_idx_find(services, Z_LVAL_P(service_id)); zval *mysql = zend_read_property(air_async_service_ce, service, ZEND_STRL("_request"), 0 TSRMLS_CC); zval **trigger_params[2]; zval *event; MAKE_STD_ZVAL(event); zval *event_params; MAKE_STD_ZVAL(event_params); array_init(event_params); Z_ADDREF_P(mysqli); add_next_index_zval(event_params, mysqli); zval *mysqli_result = NULL; if(air_mysqli_get_errno(mysqli TSRMLS_CC)){ ZVAL_STRING(event, "error", 1); }else{ ZVAL_STRING(event, "success", 1); air_call_method(&mysqli, mysqli_ce, NULL, ZEND_STRL("reap_async_query"), &mysqli_result, 0, NULL TSRMLS_CC); Z_ADDREF_P(mysqli_result); add_next_index_zval(event_params, mysqli_result); } trigger_params[0] = &event; trigger_params[1] = &event_params; zval *results = NULL; air_call_method(&mysql, air_mysql_ce, NULL, ZEND_STRL("trigger"), &results, 2, trigger_params TSRMLS_CC); if(results){ add_index_zval(responses, Z_LVAL_P(service_id), results); }else{ php_error(E_WARNING, "error on trigger event %s with no results", Z_STRVAL_P(event)); } zend_hash_index_del(Z_ARRVAL_P(services), Z_LVAL_P(service_id)); zval_ptr_dtor(&event); zval_ptr_dtor(&event_params); if(mysqli_result){ zval_ptr_dtor(&mysqli_result); } zval *mysql_config = zend_read_property(air_mysql_ce, mysql, ZEND_STRL("_config"), 0 TSRMLS_CC); zval *mode = zend_read_property(air_mysql_ce, mysql, ZEND_STRL("_mode"), 0 TSRMLS_CC); zval **release_params[3] = {&mysqli, &mysql_config, &mode}; air_call_static_method(air_mysql_keeper_ce, "release", NULL, 3, release_params); }AIR_HASH_FOREACH_END();
PHP_METHOD(air_mysql_waiter, step_1) { AIR_INIT_THIS; zval *context = zend_read_property(Z_OBJCE_P(self), self, ZEND_STRL("_context"), 0 TSRMLS_CC); zval *wait_pool = air_arr_find(context, ZEND_STRS("pool"));; zval *timeout; MAKE_STD_ZVAL(timeout); ZVAL_LONG(timeout, 0); zend_class_entry *mysqli_ce = air_get_ce(ZEND_STRL("mysqli") TSRMLS_CC); zval *mysqli; zval *errors, *reads, *rejects; MAKE_STD_ZVAL(errors); ZVAL_ZVAL(errors, wait_pool, 1, 0); MAKE_STD_ZVAL(reads); ZVAL_ZVAL(reads, wait_pool, 1, 0); MAKE_STD_ZVAL(rejects); ZVAL_ZVAL(rejects, wait_pool, 1, 0); zval **poll_params[4] = {&reads, &errors, &rejects, &timeout}; zval *count; air_call_static_method(mysqli_ce, "poll", &count, 4, poll_params); if(Z_LVAL_P(count)){ add_assoc_long(context, "step", 2); } add_assoc_zval(context, "reads", reads); zval_ptr_dtor(&errors); zval_ptr_dtor(&rejects); zval_ptr_dtor(&timeout); zval_ptr_dtor(&count); }
ZEND_RESULT_CODE air_router_route_apply_subpats(zval *r, zval *subpats, char *key, int key_len, char *ro, int ro_len) { zval *tmp_val = air_arr_find(r, key, key_len); if(tmp_val){ char *tmp = Z_STRVAL_P(tmp_val); if(tmp[0] == '$'){ tmp_val = air_arr_find(subpats, tmp+1, strlen(tmp)); if(tmp_val){ add_assoc_stringl_ex(subpats, key, key_len, Z_STRVAL_P(tmp_val), Z_STRLEN_P(tmp_val), 1); }else{ php_error(E_NOTICE, "ref name '%s' not found in route rule '%s', and 'index' will be set instead,", tmp, ro TSRMLS_CC); add_assoc_stringl_ex(subpats, key, key_len, ZEND_STRL("index"), 1); } }else{ add_assoc_stringl_ex(subpats, key, key_len, Z_STRVAL_P(tmp_val), Z_STRLEN_P(tmp_val), 1); } return SUCCESS; } return FAILURE; }
int air_mysql_keeper_get_mysqli(zval **pp_mysqli, zval *config, int mode TSRMLS_DC){ zval *mysqli = air_new_object(ZEND_STRL("mysqli") TSRMLS_CC); air_call_method(&mysqli, Z_OBJCE_P(mysqli), NULL, ZEND_STRL("init"), NULL, 0, NULL TSRMLS_CC); zval **params[7]; zval *host, *user, *pass, *db, *port, *sock, *flag, *nil; MAKE_STD_ZVAL(nil); ZVAL_NULL(nil); zval *auth = air_arr_find(config, ZEND_STRS("auth")); zval *mode_auth = air_arr_idx_find(auth, mode); user = air_arr_find(mode_auth, ZEND_STRS("username")); pass = air_arr_find(mode_auth, ZEND_STRS("password")); params[1] = user? &user: &nil; params[2] = pass? &pass: &nil; params[3] = &nil; MAKE_STD_ZVAL(flag); ZVAL_LONG(flag, MYSQLI_FOUND_ROWS); params[6] = &flag; zval *pool = air_arr_find(config, ZEND_STRS("pool")); zval *mode_pool = air_arr_idx_find(pool, mode); zval *rand_arr[1] = {mode_pool}; zval *mode_hps; zval *ret; while(1){ zval *arr_idx = air_call_func("array_rand", 1, rand_arr); if(!arr_idx){ return -3; } mode_hps = air_arr_idx_find(mode_pool, Z_LVAL_P(arr_idx)); host = air_arr_find(mode_hps, ZEND_STRS("host")); port = air_arr_find(mode_hps, ZEND_STRS("port")); sock = air_arr_find(mode_hps, ZEND_STRS("sock")); params[0] = host? &host: &nil; params[4] = port? &port: &nil; params[5] = sock? &sock: &nil; air_call_method(&mysqli, Z_OBJCE_P(mysqli), NULL, ZEND_STRL("real_connect"), &ret, 7, params TSRMLS_CC); if(Z_LVAL_P(ret)){ zval_ptr_dtor(&arr_idx); zval_ptr_dtor(&ret); break; }else{ zval_ptr_dtor(&ret); zend_hash_index_del(Z_ARRVAL_P(mode_pool), Z_LVAL_P(arr_idx)); zval_ptr_dtor(&arr_idx); if(!zend_hash_num_elements(Z_ARRVAL_P(mode_pool))){ return -5; } } } zval_ptr_dtor(&nil); zval_ptr_dtor(&flag); *pp_mysqli = mysqli; return 0; }
zval *air_router_route(air_router_t *self) { zval *return_value; MAKE_STD_ZVAL(return_value); ZVAL_NULL(return_value); pcre_cache_entry *pce; HashTable *ht_or, *ht_cr; zval *original_rules, *compiled_rules, **entry, *r; zval *url; url = zend_read_property(air_router_ce, self, ZEND_STRL("_url"), 0 TSRMLS_CC); original_rules = zend_read_property(air_router_ce, self, ZEND_STRL("_original_rules"), 0 TSRMLS_CC); compiled_rules = zend_read_property(air_router_ce, self, ZEND_STRL("_compiled_rules"), 0 TSRMLS_CC); ht_or = Z_ARRVAL_P(original_rules); ht_cr = Z_ARRVAL_P(compiled_rules); for( /*zend_hash_internal_pointer_reset(ht_or)*/; zend_hash_has_more_elements(ht_or) == SUCCESS; zend_hash_move_forward(ht_or) ){ if (zend_hash_get_current_data(ht_or, (void**)&entry) == FAILURE) { continue; } char *key; uint key_len = 0; ulong idx = 0; smart_str ss = {0}; char *regex = NULL; uint regex_len = 0; //lazy compiling zend_hash_get_current_key_ex(ht_or, &key, &key_len, &idx, 0, NULL); r = air_arr_find(compiled_rules, key, key_len); if (r == NULL){ MAKE_STD_ZVAL(r); array_init(r); regex = air_router_compile(key, key_len, ®ex_len); char *ca = Z_STRVAL_PP(entry); int size = 0; while(size<Z_STRLEN_PP(entry)) { if(ca[size] == '.'){ break; } size++; } if(size==0){ add_assoc_stringl_ex(r, ZEND_STRS(air_c_key), ZEND_STRS("index"), 1); }else{ add_assoc_stringl_ex(r, ZEND_STRS(air_c_key), ca, size, 1); } if(size+1>=Z_STRLEN_PP(entry)){ add_assoc_stringl_ex(r, ZEND_STRS(air_a_key), ZEND_STRS("index"), 1); }else{ add_assoc_stringl_ex(r, ZEND_STRS(air_a_key), ca+size+1, Z_STRLEN_PP(entry)-size-1, 1); } add_assoc_zval_ex(compiled_rules, key, key_len, r); smart_str_appendc(&ss, '#'); smart_str_appendl(&ss, regex, regex_len-1); smart_str_appendc(&ss, '#'); smart_str_0(&ss); efree(regex); add_assoc_stringl_ex(r, ZEND_STRS("regex"), ss.c, ss.len, 1); }else{ zval *r_r = air_arr_find(r, ZEND_STRS("regex")); if (r_r == NULL){ continue; } smart_str_appendl(&ss, Z_STRVAL_P(r_r), Z_STRLEN_P(r_r)); smart_str_0(&ss); } if(ss.len > 0){ zval *ret; pce = pcre_get_compiled_regex_cache(ss.c, ss.len TSRMLS_CC); smart_str_free(&ss); if(pce){ zval matches, *subpats; MAKE_STD_ZVAL(subpats); ZVAL_NULL(subpats); php_pcre_match_impl(pce, Z_STRVAL_P(url), Z_STRLEN_P(url), &matches, subpats/* subpats */, 0/* global */, 0/* ZEND_NUM_ARGS() >= 4 */, 0/*flags PREG_OFFSET_CAPTURE*/, 0/* start_offset */ TSRMLS_CC); if (zend_hash_num_elements(Z_ARRVAL_P(subpats)) > 0) { ret = air_arr_del_index_el(subpats); air_router_route_apply_subpats(r, ret, ZEND_STRS(air_c_key), key, key_len); air_router_route_apply_subpats(r, ret, ZEND_STRS(air_a_key), key, key_len); ZVAL_ZVAL(return_value, ret, 1, 0); zval_ptr_dtor(&ret); zval_ptr_dtor(&subpats); //move forward specially zend_hash_move_forward(ht_or); break; } zval_ptr_dtor(&subpats); } } } return return_value; }