#include "php7_ext_wrapper.h" #include "ext/standard/info.h" #include #include #include #include #include #include #include #include "common_define.h" #include "local_ip_func.h" #include "logger.h" #include "hash.h" #include "sockopt.h" #include "shared_func.h" #include "id_generator.h" #include "fastcommon.h" #define MAJOR_VERSION 1 #define MINOR_VERSION 0 #define PATCH_VERSION 7 #define PHP_IDG_RESOURCE_NAME "fastcommon_idg" #define DEFAULT_SN_FILENAME "/tmp/fastcommon_id_generator.sn" typedef struct { struct idg_context idg_context; } PHPIDGContext; static int le_consumer; static struct idg_context idg_context = {-1, 0}; #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 3) const zend_fcall_info empty_fcall_info = { 0, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0 }; #undef ZEND_BEGIN_ARG_INFO_EX #define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args) \ static zend_arg_info name[] = { \ { NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args }, #endif // Every user visible function must have an entry in fastcommon_functions[]. zend_function_entry fastcommon_functions[] = { ZEND_FE(fastcommon_version, NULL) ZEND_FE(fastcommon_gethostaddrs, NULL) ZEND_FE(fastcommon_time33_hash, NULL) ZEND_FE(fastcommon_simple_hash, NULL) ZEND_FE(fastcommon_get_line_distance_km, NULL) ZEND_FE(fastcommon_get_first_local_ip, NULL) ZEND_FE(fastcommon_get_next_local_ip, NULL) ZEND_FE(fastcommon_is_private_ip, NULL) ZEND_FE(fastcommon_id_generator_init, NULL) ZEND_FE(fastcommon_id_generator_next, NULL) ZEND_FE(fastcommon_id_generator_get_extra, NULL) ZEND_FE(fastcommon_id_generator_destroy, NULL) {NULL, NULL, NULL} /* Must be the last line */ }; zend_module_entry fastcommon_module_entry = { STANDARD_MODULE_HEADER, "fastcommon", fastcommon_functions, PHP_MINIT(fastcommon), PHP_MSHUTDOWN(fastcommon), NULL,//PHP_RINIT(fastcommon), NULL,//PHP_RSHUTDOWN(fastcommon), PHP_MINFO(fastcommon), "1.00", STANDARD_MODULE_PROPERTIES }; #ifdef COMPILE_DL_FASTCOMMON ZEND_GET_MODULE(fastcommon) #endif ZEND_RSRC_DTOR_FUNC(id_generator_dtor) { #if PHP_MAJOR_VERSION < 7 if (rsrc->ptr != NULL) { PHPIDGContext *php_idg_context = (PHPIDGContext *)rsrc->ptr; id_generator_destroy(&php_idg_context->idg_context); efree(php_idg_context); rsrc->ptr = NULL; } #else if (res->ptr != NULL) { PHPIDGContext *php_idg_context = (PHPIDGContext *)res->ptr; id_generator_destroy(&php_idg_context->idg_context); efree(php_idg_context); res->ptr = NULL; } #endif } PHP_MINIT_FUNCTION(fastcommon) { log_init(); le_consumer = zend_register_list_destructors_ex(id_generator_dtor, NULL, PHP_IDG_RESOURCE_NAME, module_number); return SUCCESS; } PHP_MSHUTDOWN_FUNCTION(fastcommon) { log_destroy(); return SUCCESS; } PHP_RINIT_FUNCTION(fastcommon) { return SUCCESS; } PHP_RSHUTDOWN_FUNCTION(fastcommon) { return SUCCESS; } PHP_MINFO_FUNCTION(fastcommon) { char mc_info[64]; sprintf(mc_info, "fastcommon v%d.%02d support", MAJOR_VERSION, MINOR_VERSION); php_info_print_table_start(); php_info_print_table_header(2, mc_info, "enabled"); php_info_print_table_end(); } /* string fastcommon_version() return client library version */ ZEND_FUNCTION(fastcommon_version) { char szVersion[16]; int len; len = sprintf(szVersion, "%d.%d.%d", MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION); ZEND_RETURN_STRINGL(szVersion, len, 1); } /* array fastcommon_gethostaddrs([string if_alias_prefix]); return false for fail, array for success */ ZEND_FUNCTION(fastcommon_gethostaddrs) { int argc; char *if_alias_prefix; zend_size_t if_prefix_len; int count; int uniq_count; int i; int k; int alias_count; char ip_addresses[FAST_MAX_LOCAL_IP_ADDRS][IP_ADDRESS_SIZE]; char *uniq_ips[FAST_MAX_LOCAL_IP_ADDRS]; char *if_alias_prefixes[1]; argc = ZEND_NUM_ARGS(); if (argc > 1) { logError("file: "__FILE__", line: %d, " "fastcommon_gethostaddrs parameters count: %d is invalid", __LINE__, argc); RETURN_BOOL(false); } if_alias_prefix = NULL; if_prefix_len = 0; if (zend_parse_parameters(argc TSRMLS_CC, "|s", &if_alias_prefix, &if_prefix_len) == FAILURE) { logError("file: "__FILE__", line: %d, " "zend_parse_parameters fail!", __LINE__); RETURN_BOOL(false); } if (if_alias_prefix == NULL || if_prefix_len == 0) { alias_count = 0; if_alias_prefixes[0] = NULL; } else { alias_count = 1; if_alias_prefixes[0] = if_alias_prefix; } count = 0; if (gethostaddrs(if_alias_prefixes, alias_count, ip_addresses, FAST_MAX_LOCAL_IP_ADDRS, &count) != 0) { RETURN_BOOL(false); } uniq_count = 0; for (k=0; k 5) { logError("file: "__FILE__", line: %d, " "fastcommon_id_generator_init parameters count: %d is invalid", __LINE__, argc); RETURN_BOOL(false); } filename = DEFAULT_SN_FILENAME; filename_len = 0; machine_id = 0; mid_bits = 16; extra_bits = 0; sn_bits = 16; if (zend_parse_parameters(argc TSRMLS_CC, "|sllll", &filename, &filename_len, &machine_id, &mid_bits, &extra_bits, &sn_bits) == FAILURE) { logError("file: "__FILE__", line: %d, " "zend_parse_parameters fail!", __LINE__); RETURN_BOOL(false); } php_idg_context = (PHPIDGContext *)emalloc(sizeof(PHPIDGContext)); if (php_idg_context == NULL) { logError("file: "__FILE__", line: %d, " "emalloc %d bytes fail!", __LINE__, (int)sizeof(PHPIDGContext)); RETURN_BOOL(false); } if (id_generator_init_extra(&php_idg_context->idg_context, filename, machine_id, mid_bits, extra_bits, sn_bits) != 0) { RETURN_BOOL(false); } ZEND_REGISTER_RESOURCE(return_value, php_idg_context, le_consumer); } /* long/string fastcommon_id_generator_next([int extra = 0, $handle = NULL]) return id for success, false for fail return long in 64 bits OS, return string in 32 bits Os */ ZEND_FUNCTION(fastcommon_id_generator_next) { int argc; long extra; int64_t id; zval *zhandle; PHPIDGContext *php_idg_context; struct idg_context *context; argc = ZEND_NUM_ARGS(); if (argc > 2) { logError("file: "__FILE__", line: %d, " "fastcommon_id_generator_next parameters count: %d is invalid", __LINE__, argc); RETURN_BOOL(false); } extra = 0; zhandle = NULL; if (zend_parse_parameters(argc TSRMLS_CC, "|lz", &extra, &zhandle) == FAILURE) { logError("file: "__FILE__", line: %d, " "zend_parse_parameters fail!", __LINE__); RETURN_BOOL(false); } if (zhandle != NULL && !ZVAL_IS_NULL(zhandle)) { ZEND_FETCH_RESOURCE(php_idg_context, PHPIDGContext *, &zhandle, -1, PHP_IDG_RESOURCE_NAME, le_consumer); context = &php_idg_context->idg_context; } else { context = &idg_context; if (context->fd < 0) { if (id_generator_init(context, DEFAULT_SN_FILENAME) != 0) { RETURN_BOOL(false); } } } if (id_generator_next_extra(context, extra, &id) != 0) { RETURN_BOOL(false); } #if OS_BITS == 64 RETURN_LONG(id); #else { char buff[32]; int len; len = sprintf(buff, "%"PRId64, id); ZEND_RETURN_STRINGL(buff, len, 1); } #endif } /* int fastcommon_id_generator_get_extra(long id [, $handle = NULL]) return the extra data */ ZEND_FUNCTION(fastcommon_id_generator_get_extra) { int argc; long id; zval *zhandle; PHPIDGContext *php_idg_context; struct idg_context *context; argc = ZEND_NUM_ARGS(); if (argc > 2) { logError("file: "__FILE__", line: %d, " "fastcommon_id_generator_get_extra parameters count: %d is invalid", __LINE__, argc); RETURN_BOOL(false); } zhandle = NULL; if (zend_parse_parameters(argc TSRMLS_CC, "l|z", &id, &zhandle) == FAILURE) { logError("file: "__FILE__", line: %d, " "zend_parse_parameters fail!", __LINE__); RETURN_BOOL(false); } if (zhandle != NULL && !ZVAL_IS_NULL(zhandle)) { ZEND_FETCH_RESOURCE(php_idg_context, PHPIDGContext *, &zhandle, -1, PHP_IDG_RESOURCE_NAME, le_consumer); context = &php_idg_context->idg_context; } else { context = &idg_context; } if (context->fd < 0) { logError("file: "__FILE__", line: %d, " "must call fastcommon_id_generator_init first", __LINE__); RETURN_BOOL(false); } RETURN_LONG(id_generator_get_extra(context, id)); } /* bool fastcommon_id_generator_destroy([$handle = NULL]) return true for success, false for fail */ ZEND_FUNCTION(fastcommon_id_generator_destroy) { int argc; zval *zhandle; PHPIDGContext *php_idg_context; struct idg_context *context; argc = ZEND_NUM_ARGS(); if (argc > 1) { logError("file: "__FILE__", line: %d, " "fastcommon_id_generator_destroy parameters count: %d is invalid", __LINE__, argc); RETURN_BOOL(false); } zhandle = NULL; if (zend_parse_parameters(argc TSRMLS_CC, "|z", &zhandle) == FAILURE) { logError("file: "__FILE__", line: %d, " "zend_parse_parameters fail!", __LINE__); RETURN_BOOL(false); } if (zhandle != NULL && !ZVAL_IS_NULL(zhandle)) { ZEND_FETCH_RESOURCE(php_idg_context, PHPIDGContext *, &zhandle, -1, PHP_IDG_RESOURCE_NAME, le_consumer); context = &php_idg_context->idg_context; } else { context = &idg_context; } id_generator_destroy(context); RETURN_BOOL(true); }