diff --git a/HISTORY b/HISTORY index 7d0f629..e4ed46d 100644 --- a/HISTORY +++ b/HISTORY @@ -1,8 +1,9 @@ -Version 1.28 2016-05-18 +Version 1.28 2016-05-19 * id generator support extra bits * change inet_aton to inet_pton * connect by ip and connection pool support ipv6 + * id generator in php extension support multi instance Version 1.27 2016-04-15 * add function fd_set_cloexec diff --git a/php-fastcommon/fastcommon.c b/php-fastcommon/fastcommon.c index f6e61d5..0a44c37 100644 --- a/php-fastcommon/fastcommon.c +++ b/php-fastcommon/fastcommon.c @@ -18,10 +18,17 @@ #define MAJOR_VERSION 1 #define MINOR_VERSION 0 -#define PATCH_VERSION 6 +#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) @@ -66,9 +73,33 @@ zend_module_entry fastcommon_module_entry = { 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; } @@ -368,9 +399,9 @@ ZEND_FUNCTION(fastcommon_is_private_ip) } /* -bool fastcommon_id_generator_init([string filename = "/tmp/fastcommon_id_generator.sn", +resource fastcommon_id_generator_init([string filename = "/tmp/fastcommon_id_generator.sn", int machine_id = 0, int mid_bits = 16, int extra_bits = 0, int sn_bits = 16]) -return true for success, false for fail +return resource handle for success, false for fail */ ZEND_FUNCTION(fastcommon_id_generator_init) { @@ -381,6 +412,7 @@ ZEND_FUNCTION(fastcommon_id_generator_init) long extra_bits; long sn_bits; char *filename; + PHPIDGContext *php_idg_context; argc = ZEND_NUM_ARGS(); if (argc > 5) { @@ -405,23 +437,25 @@ ZEND_FUNCTION(fastcommon_id_generator_init) RETURN_BOOL(false); } - if (idg_context.fd >= 0) { - logWarning("file: "__FILE__", line: %d, " - "already inited!", __LINE__); + 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(&idg_context, filename, + if (id_generator_init_extra(&php_idg_context->idg_context, filename, machine_id, mid_bits, extra_bits, sn_bits) != 0) { RETURN_BOOL(false); } - RETURN_BOOL(true); + ZEND_REGISTER_RESOURCE(return_value, php_idg_context, le_consumer); } /* -long/string fastcommon_id_generator_next([int extra = 0]) +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 */ @@ -430,29 +464,43 @@ 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 > 1) { + if (argc > 2) { logError("file: "__FILE__", line: %d, " "fastcommon_id_generator_next parameters count: %d is invalid", __LINE__, argc); RETURN_BOOL(false); } extra = 0; - if (zend_parse_parameters(argc TSRMLS_CC, "|l", &extra) == FAILURE) + 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 (idg_context.fd < 0) { - if (id_generator_init(&idg_context, DEFAULT_SN_FILENAME) != 0) { - 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(&idg_context, extra, &id) != 0) { + if (id_generator_next_extra(context, extra, &id) != 0) { RETURN_BOOL(false); } @@ -469,54 +517,92 @@ ZEND_FUNCTION(fastcommon_id_generator_next) } /* -int fastcommon_id_generator_get_extra(long id) +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 != 1) { + if (argc > 2) { logError("file: "__FILE__", line: %d, " "fastcommon_id_generator_get_extra parameters count: %d is invalid", __LINE__, argc); RETURN_BOOL(false); } - if (zend_parse_parameters(argc TSRMLS_CC, "l", &id) == FAILURE) + 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 (idg_context.fd < 0) { + + 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(&idg_context, id)); + RETURN_LONG(id_generator_get_extra(context, id)); } /* -bool fastcommon_id_generator_destroy() +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 != 0) { + if (argc > 1) { logError("file: "__FILE__", line: %d, " "fastcommon_id_generator_destroy parameters count: %d is invalid", __LINE__, argc); RETURN_BOOL(false); } - id_generator_destroy(&idg_context); + 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); } diff --git a/php-fastcommon/php-fastcommon.spec.in b/php-fastcommon/php-fastcommon.spec.in index c38a733..053efca 100644 --- a/php-fastcommon/php-fastcommon.spec.in +++ b/php-fastcommon/php-fastcommon.spec.in @@ -1,7 +1,7 @@ %define php_inidir %(php --ini | head -n 1 | awk -F ':' '{print $2;}' | sed 's/ //g') %define php_extdir %(php-config --extension-dir 2>/dev/null) Name: php-fastcommon -Version: 1.0.6 +Version: 1.0.7 Release: 1%{?dist} Summary: The php extension for libfastcommon License: GPL diff --git a/php-fastcommon/test.php b/php-fastcommon/test.php index d2f8687..46f508a 100644 --- a/php-fastcommon/test.php +++ b/php-fastcommon/test.php @@ -17,15 +17,27 @@ while (($next_ip=fastcommon_get_next_local_ip($next_ip))) } //fastcommon_id_generator_init(); -fastcommon_id_generator_init("/tmp/sn.txt", 0, 8, 10, 14); -$id = fastcommon_id_generator_next(1024); -printf("%d %X, extra: %d\n", $id, $id, fastcommon_id_generator_get_extra($id)); +$handle1 = fastcommon_id_generator_init("/tmp/sn1.txt", 0, 16, 0, 16); +$handle2 = fastcommon_id_generator_init("/tmp/sn2.txt", 0, 8, 8, 16); -for ($i=0; $i<1024; $i++) { - $id = fastcommon_id_generator_next($i); - printf("%d %X, extra: %d\n", $id, $id, fastcommon_id_generator_get_extra($id)); +$id = fastcommon_id_generator_next(1, $handle1); +printf("id1: %d %X, extra: %d\n", $id, $id, fastcommon_id_generator_get_extra($id, $handle1)); + +$id = fastcommon_id_generator_next(2, $handle2); +printf("id2: %d %X, extra: %d\n", $id, $id, fastcommon_id_generator_get_extra($id, $handle2)); + +$handle = fastcommon_id_generator_init("/tmp/sn.txt", 0, 8, 10, 14); +$id = fastcommon_id_generator_next(512, $handle); +printf("%d %X, extra: %d\n", $id, $id, fastcommon_id_generator_get_extra($id, $handle)); + +for ($i=0; $i<10; $i++) { + $id = fastcommon_id_generator_next($i, $handle); + printf("%d %X, extra: %d\n", $id, $id, fastcommon_id_generator_get_extra($id, $handle)); } -fastcommon_id_generator_destroy(); +fastcommon_id_generator_destroy($handle); +fastcommon_id_generator_destroy($handle1); +fastcommon_id_generator_destroy($handle2); + diff --git a/src/sockopt.c b/src/sockopt.c index 5ad0a6e..c933bab 100644 --- a/src/sockopt.c +++ b/src/sockopt.c @@ -706,7 +706,7 @@ in_addr_t getIpaddrByName(const char *name, char *buff, const int bufferSize) return INADDR_NONE; } - addr_list = (in_addr_t **)ent->h_addr_list; + addr_list = (in_addr_t **)ent->h_addr_list; if (addr_list[0] == NULL) { return INADDR_NONE;