284 lines
8.0 KiB
C
284 lines
8.0 KiB
C
/*
|
|
+----------------------------------------------------------------------+
|
|
| 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. |
|
|
+----------------------------------------------------------------------+
|
|
| 版权归属: yitter(yitter@126.com) |
|
|
| Author: amuluowin(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;
|
|
|
|
static uint16_t wid_num = 0;
|
|
|
|
ZEND_DECLARE_MODULE_GLOBALS(snowdrift)
|
|
|
|
/* {{{ 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.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", "5", 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)
|
|
STD_PHP_INI_ENTRY("snowdrift.Multi", "0", PHP_INI_SYSTEM, OnUpdateLongGEZero, Multi, zend_snowdrift_globals, snowdrift_globals)
|
|
PHP_INI_END()
|
|
|
|
/* }}} */
|
|
|
|
static int snowdrift_init()
|
|
{
|
|
if (SD_G(MaxSeqNumber) != 0 && SD_G(MaxSeqNumber) < SD_G(MinSeqNumber))
|
|
{
|
|
return FAILURE;
|
|
}
|
|
wid_num = (-1L << SD_G(WorkerIdBitLength)) ^ -1L;
|
|
if (SD_G(Multi) > 0)
|
|
{
|
|
shmctx.size = wid_num * sizeof(snowflake);
|
|
if (shm_alloc(&shmctx) == -1)
|
|
{
|
|
return FAILURE;
|
|
}
|
|
sf = (snowflake *)shmctx.addr;
|
|
int i;
|
|
for (i = 0; i < wid_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);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
shmctx.size = sizeof(snowflake);
|
|
if (shm_alloc(&shmctx) == -1)
|
|
{
|
|
return FAILURE;
|
|
}
|
|
sf = (snowflake *)shmctx.addr;
|
|
sf->Method = SD_G(Method);
|
|
sf->BaseTime = SD_G(BaseTime);
|
|
sf->WorkerId = SD_G(WorkerId);
|
|
sf->WorkerIdBitLength = SD_G(WorkerIdBitLength);
|
|
sf->SeqBitLength = SD_G(SeqBitLength);
|
|
sf->MaxSeqNumber = SD_G(MaxSeqNumber);
|
|
sf->MinSeqNumber = SD_G(MinSeqNumber);
|
|
sf->TopOverCostCount = SD_G(TopOverCostCount);
|
|
Config(sf);
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
PHP_METHOD(snowdrift, NextId)
|
|
{
|
|
zend_long wid = SD_G(WorkerId);
|
|
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &wid) == FAILURE)
|
|
{
|
|
RETURN_FALSE;
|
|
}
|
|
snowflake *flake;
|
|
if (SD_G(Multi) == 0)
|
|
{
|
|
flake = sf;
|
|
}
|
|
else
|
|
{
|
|
wid--;
|
|
if (wid < 0 || wid > wid_num)
|
|
{
|
|
zend_throw_exception_ex(NULL, 0, "wid error! wid between 1 and %d", wid_num);
|
|
RETURN_NULL();
|
|
}
|
|
flake = (sf + wid);
|
|
}
|
|
|
|
RETURN_LONG(NextId(flake));
|
|
}
|
|
|
|
PHP_METHOD(snowdrift, NextNumId)
|
|
{
|
|
zend_long num = 1;
|
|
zend_long wid = SD_G(WorkerId);
|
|
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|ll", &num, &wid) == FAILURE)
|
|
{
|
|
RETURN_FALSE;
|
|
}
|
|
snowflake *flake;
|
|
if (SD_G(Multi) == 0)
|
|
{
|
|
flake = sf;
|
|
}
|
|
else
|
|
{
|
|
wid--;
|
|
if (wid < 0 || wid > wid_num)
|
|
{
|
|
zend_throw_exception_ex(NULL, 0, "wid error! wid between 1 and %d", wid_num);
|
|
RETURN_NULL();
|
|
}
|
|
flake = (sf + wid);
|
|
}
|
|
|
|
array_init(return_value);
|
|
int i;
|
|
for (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
|