增加PHP扩展
This commit is contained in:
247
PHP/snowdrift.c
Normal file
247
PHP/snowdrift.c
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| snowdrift |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2018 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: 63851587@qq.com |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "zend_exceptions.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "src/snowflake/shm.h"
|
||||
#include "php_snowdrift.h"
|
||||
#include "src/snowflake/snowflake.h"
|
||||
|
||||
/* True global resources - no need for thread safety here */
|
||||
static struct shm shmctx;
|
||||
static snowflake *sf;
|
||||
zend_class_entry snowdrift_ce;
|
||||
|
||||
uint8_t num = 0;
|
||||
|
||||
/* {{{ PHP_INI */
|
||||
|
||||
PHP_INI_BEGIN()
|
||||
STD_PHP_INI_ENTRY("snowdrift.Method", "1", PHP_INI_SYSTEM, OnUpdateLongGEZero, Method, zend_snowdrift_globals, snowdrift_globals)
|
||||
STD_PHP_INI_ENTRY("snowdrift.BaseTime", "1582136402000", PHP_INI_SYSTEM, OnUpdateLongGEZero, BaseTime, zend_snowdrift_globals, snowdrift_globals)
|
||||
STD_PHP_INI_ENTRY("snowdrift.WorkerId", "1", PHP_INI_SYSTEM, OnUpdateLongGEZero, WorkerId, zend_snowdrift_globals, snowdrift_globals)
|
||||
STD_PHP_INI_ENTRY("snowdrift.WorkerIdNum", "1", PHP_INI_SYSTEM, OnUpdateLongGEZero, WorkerIdNum, zend_snowdrift_globals, snowdrift_globals)
|
||||
STD_PHP_INI_ENTRY("snowdrift.WorkerIdBitLength", "6", PHP_INI_SYSTEM, OnUpdateLongGEZero, WorkerIdBitLength, zend_snowdrift_globals, snowdrift_globals)
|
||||
STD_PHP_INI_ENTRY("snowdrift.SeqBitLength", "6", PHP_INI_SYSTEM, OnUpdateLongGEZero, SeqBitLength, zend_snowdrift_globals, snowdrift_globals)
|
||||
STD_PHP_INI_ENTRY("snowdrift.MaxSeqNumber", "0", PHP_INI_SYSTEM, OnUpdateLongGEZero, MaxSeqNumber, zend_snowdrift_globals, snowdrift_globals)
|
||||
STD_PHP_INI_ENTRY("snowdrift.MinSeqNumber", "0", PHP_INI_SYSTEM, OnUpdateLongGEZero, MinSeqNumber, zend_snowdrift_globals, snowdrift_globals)
|
||||
STD_PHP_INI_ENTRY("snowdrift.TopOverCostCount", "2000", PHP_INI_SYSTEM, OnUpdateLongGEZero, TopOverCostCount, zend_snowdrift_globals, snowdrift_globals)
|
||||
PHP_INI_END()
|
||||
|
||||
/* }}} */
|
||||
|
||||
static int snowdrift_init()
|
||||
{
|
||||
num = (-1L << SD_G(WorkerIdBitLength)) ^ -1L;
|
||||
if (SD_G(WorkerIdNum) < num)
|
||||
{
|
||||
num = SD_G(WorkerIdNum);
|
||||
}
|
||||
shmctx.size = num * sizeof(snowflake);
|
||||
if (shm_alloc(&shmctx) == -1)
|
||||
{
|
||||
zend_throw_exception_ex(NULL, 0, "shared memory malloc failed");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
if (SD_G(MaxSeqNumber) <= SD_G(MinSeqNumber))
|
||||
{
|
||||
zend_throw_exception_ex(NULL, 0, "MaxSeqNumber must GE then MinSeqNumber");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
bzero(shmctx.addr, num * sizeof(snowflake));
|
||||
sf = (snowflake *)shmctx.addr;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
snowflake *tmp = (sf + i);
|
||||
tmp->Method = SD_G(Method);
|
||||
tmp->BaseTime = SD_G(BaseTime);
|
||||
tmp->WorkerId = i + 1;
|
||||
tmp->WorkerIdBitLength = SD_G(WorkerIdBitLength);
|
||||
tmp->SeqBitLength = SD_G(SeqBitLength);
|
||||
tmp->MaxSeqNumber = SD_G(MaxSeqNumber);
|
||||
tmp->MinSeqNumber = SD_G(MinSeqNumber);
|
||||
tmp->TopOverCostCount = SD_G(TopOverCostCount);
|
||||
Config(tmp);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
PHP_METHOD(snowdrift, NextId)
|
||||
{
|
||||
zend_long wid = SD_G(WorkerId);
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &wid) == FAILURE)
|
||||
{
|
||||
RETURN_FALSE;
|
||||
}
|
||||
wid--;
|
||||
if (wid < 0 || wid > num - 1)
|
||||
{
|
||||
zend_throw_exception_ex(NULL, 0, "wid error! wid between 0 and %d", num - 1);
|
||||
RETURN_NULL();
|
||||
}
|
||||
snowflake *flake = (sf + wid);
|
||||
RETURN_LONG(NextId(flake));
|
||||
}
|
||||
|
||||
/** 这种方式性能比不上PHP直接循环调用NextId快
|
||||
*/
|
||||
PHP_METHOD(snowdrift, NextNumId)
|
||||
{
|
||||
zend_long num = 1;
|
||||
zend_long wid = SD_G(WorkerId);
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &num, &wid) == FAILURE)
|
||||
{
|
||||
RETURN_FALSE;
|
||||
}
|
||||
wid--;
|
||||
if (wid < 0 || wid > num - 1)
|
||||
{
|
||||
zend_throw_exception_ex(NULL, 0, "wid error! wid between 0 and %d", num - 1);
|
||||
RETURN_NULL();
|
||||
}
|
||||
snowflake *flake = (sf + wid);
|
||||
array_init(return_value);
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
add_next_index_long(return_value, NextId(flake));
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ PHP_MSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_MSHUTDOWN_FUNCTION(snowdrift)
|
||||
{
|
||||
UNREGISTER_INI_ENTRIES();
|
||||
shm_free(&shmctx);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* Remove if there's nothing to do at request start */
|
||||
/* {{{ PHP_RINIT_FUNCTION
|
||||
*/
|
||||
PHP_RINIT_FUNCTION(snowdrift)
|
||||
{
|
||||
#if defined(COMPILE_DL_SNOWFLAKE) && defined(ZTS)
|
||||
ZEND_TSRMLS_CACHE_UPDATE();
|
||||
#endif
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* Remove if there's nothing to do at request end */
|
||||
/* {{{ PHP_RSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_RSHUTDOWN_FUNCTION(snowdrift)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
PHP_MINFO_FUNCTION(snowdrift)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "snowfrift support", "enabled");
|
||||
php_info_print_table_row(2, "Version", PHP_SNOWDRIFT_VERSION);
|
||||
php_info_print_table_end();
|
||||
|
||||
/* Remove comments if you have entries in php.ini */
|
||||
DISPLAY_INI_ENTRIES();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ arginfo
|
||||
*/
|
||||
ZEND_BEGIN_ARG_INFO(arginfo_snowdrift_void, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_snowdrift_nextid, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, wid)
|
||||
ZEND_END_ARG_INFO()
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_snowdrift_nextnumid, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, num)
|
||||
ZEND_ARG_INFO(0, wid)
|
||||
ZEND_END_ARG_INFO()
|
||||
/* }}} */
|
||||
|
||||
/* {{{ snowdrift_functions[]
|
||||
*
|
||||
* Every user visible function must have an entry in snowdrift_functions[].
|
||||
*/
|
||||
const zend_function_entry snowdrift_functions[] = {
|
||||
PHP_FE_END /* Must be the last line in snowdrift_functions[] */
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ snowdrift_method[]
|
||||
*
|
||||
* Every user visible function must have an entry in snowdrift_functions[].
|
||||
*/
|
||||
static const zend_function_entry snowdrift_methods[] = {
|
||||
PHP_ME(snowdrift, NextId, arginfo_snowdrift_nextid, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
|
||||
PHP_ME(snowdrift, NextNumId, arginfo_snowdrift_nextnumid, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION
|
||||
*/
|
||||
PHP_MINIT_FUNCTION(snowdrift)
|
||||
{
|
||||
INIT_CLASS_ENTRY(snowdrift_ce, "snowdrift", snowdrift_methods);
|
||||
REGISTER_INI_ENTRIES();
|
||||
zend_register_internal_class(&snowdrift_ce);
|
||||
|
||||
if (snowdrift_init() == FAILURE)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ snowdrift_module_entry
|
||||
*/
|
||||
zend_module_entry snowdrift_module_entry = {
|
||||
STANDARD_MODULE_HEADER,
|
||||
"snowdrift",
|
||||
snowdrift_functions,
|
||||
PHP_MINIT(snowdrift),
|
||||
PHP_MSHUTDOWN(snowdrift),
|
||||
PHP_RINIT(snowdrift), /* Replace with NULL if there's nothing to do at
|
||||
request start */
|
||||
PHP_RSHUTDOWN(snowdrift), /* Replace with NULL if there's nothing to do at
|
||||
request end */
|
||||
PHP_MINFO(snowdrift),
|
||||
PHP_SNOWDRIFT_VERSION,
|
||||
STANDARD_MODULE_PROPERTIES};
|
||||
/* }}} */
|
||||
|
||||
#ifdef COMPILE_DL_SNOWDRIFT
|
||||
#ifdef ZTS
|
||||
ZEND_TSRMLS_CACHE_DEFINE()
|
||||
#endif
|
||||
ZEND_GET_MODULE(snowdrift)
|
||||
#endif
|
||||
Reference in New Issue
Block a user